package com.engine.salary.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.api.formmode.mybatis.util.SqlProxyHandle;
import com.cloudstore.eccom.pc.table.WeaTableColumn;
import com.cloudstore.eccom.result.WeaResultMsg;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.component.SalaryWeaTable;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.encrypt.EncryptUtil;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.siarchives.param.InsuranceArchivesListParam;
import com.engine.salary.entity.siarchives.param.SIArchiveImportParam;
import com.engine.salary.entity.siarchives.po.*;
import com.engine.salary.entity.sicategory.po.ICategoryPO;
import com.engine.salary.entity.sischeme.bo.InsuranceSchemeBO;
import com.engine.salary.entity.sischeme.dto.InsuranceSchemeDTO;
import com.engine.salary.entity.sischeme.dto.InsuranceSchemeDetailDTO;
import com.engine.salary.entity.sischeme.dto.InsuranceSchemeListDTO;
import com.engine.salary.entity.sischeme.param.InsuranceSchemeDetailUpdateParam;
import com.engine.salary.entity.sischeme.param.InsuranceSchemeParam;
import com.engine.salary.entity.sischeme.param.InsuranceSchemeReqParam;
import com.engine.salary.entity.sischeme.po.InsuranceSchemeDetailPO;
import com.engine.salary.entity.sischeme.po.InsuranceSchemePO;
import com.engine.salary.entity.sischeme.vo.InsuranceSchemeFormVO;
import com.engine.salary.entity.sischeme.vo.SISchemeTableVO;
import com.engine.salary.entity.taxagent.dto.TaxAgentManageRangeEmployeeDTO;
import com.engine.salary.entity.taxagent.param.TaxAgentManageRangeSaveParam;
import com.engine.salary.entity.taxagent.param.TaxAgentQueryParam;
import com.engine.salary.entity.taxagent.param.TaxAgentRangeSaveParam;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.enums.SalaryRoundingModeEnum;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.auth.AuthFilterTypeEnum;
import com.engine.salary.enums.salarysob.TargetTypeEnum;
import com.engine.salary.enums.siaccount.EmployeeStatusEnum;
import com.engine.salary.enums.sicategory.*;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.datacollection.EmployMapper;
import com.engine.salary.mapper.siaccount.SIAccountUtilMapper;
import com.engine.salary.mapper.siarchives.FundSchemeMapper;
import com.engine.salary.mapper.siarchives.InsuranceBaseInfoMapper;
import com.engine.salary.mapper.siarchives.OtherSchemeMapper;
import com.engine.salary.mapper.siarchives.SocialSchemeMapper;
import com.engine.salary.mapper.sicategory.ICategoryMapper;
import com.engine.salary.mapper.sischeme.InsuranceSchemeDetailMapper;
import com.engine.salary.mapper.sischeme.InsuranceSchemeMapper;
import com.engine.salary.mapper.sys.SalarySysConfMapper;
import com.engine.salary.mapper.taxagent.TaxAgentMapper;
import com.engine.salary.service.*;
import com.engine.salary.service.auth.AuthService;
import com.engine.salary.service.auth.AuthServiceImpl;
import com.engine.salary.sys.entity.po.SalarySysConfPO;
import com.engine.salary.sys.entity.vo.OrderRuleVO;
import com.engine.salary.sys.enums.OpenEnum;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.*;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelParseHelper;
import com.engine.salary.util.excel.ExcelSupport;
import com.engine.salary.util.excel.ExcelUtilPlus;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import weaver.file.ImageFileManager;
import weaver.general.Util;
import weaver.hrm.User;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.engine.salary.sys.constant.SalarySysConstant.WEL_BASE_AUTO_ADJUST;
import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX;

/**
 * @Author weaver_cl
 * @Description:
 * @Date 2022/3/7
 * @Version V1.0
 **/
@Slf4j
public class SISchemeServiceImpl extends Service implements SISchemeService {
    private EncryptUtil encryptUtil = new EncryptUtil();

    private SocialSchemeMapper getSocialSchemeMapper() {
        return MapperProxyFactory.getProxy(SocialSchemeMapper.class);
    }

    private FundSchemeMapper getFundSchemeMapper() {
        return MapperProxyFactory.getProxy(FundSchemeMapper.class);
    }

    private OtherSchemeMapper getOtherSchemeMapper() {
        return MapperProxyFactory.getProxy(OtherSchemeMapper.class);
    }

    private InsuranceSchemeMapper getInsuranceSchemeMapper() {
        return MapperProxyFactory.getProxy(InsuranceSchemeMapper.class);
    }

    private TaxAgentMapper getTaxAgentMapper() {
        return MapperProxyFactory.getProxy(TaxAgentMapper.class);
    }

    private ICategoryMapper getICategoryMapper() {
        return MapperProxyFactory.getProxy(ICategoryMapper.class);
    }

    private SISchemeService getSiSchemeService() {
        return ServiceUtil.getService(SISchemeServiceImpl.class, user);
    }


    private TaxAgentService getTaxAgentService() {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private InsuranceSchemeDetailMapper getInsuranceSchemeDetailMapper() {
        return MapperProxyFactory.getProxy(InsuranceSchemeDetailMapper.class);
    }

    private SIImportService getSIImportService() {
        return ServiceUtil.getService(SIImportServiceImpl.class, user);
    }

//    private SIArchivesBiz siArchivesBiz = new SIArchivesBiz();
//    private SISchemeBiz siSchemeBiz = new SISchemeBiz();

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return (SalaryEmployeeService) ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private SalarySysConfMapper getSalarySysConfMapper() {
        return SqlProxyHandle.getProxy(SalarySysConfMapper.class);
    }

    private SalarySysConfService getSalarySysConfService(User user) {
        return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
    }

    private InsuranceBaseInfoMapper getInsuranceBaseInfoMapper() {
        return MapperProxyFactory.getProxy(InsuranceBaseInfoMapper.class);
    }

    public TaxAgentManageRangeService getTaxAgentManageRangeService(User user) {
        return ServiceUtil.getService(TaxAgentManageRangeServiceImpl.class, user);
    }

    public SIArchivesService getSIArchivesService(User user) {
        return ServiceUtil.getService(SIArchivesServiceImpl.class,user);
    }

    private SIAccountUtilMapper getSIAccountUtilMapper() {
        return SqlProxyHandle.getProxy(SIAccountUtilMapper.class);
    }

    private EmployMapper getEmployMapper() {
        return MapperProxyFactory.getProxy(EmployMapper.class);
    }

    public AuthService getAuthService(User user) {
        return ServiceUtil.getService(AuthServiceImpl.class, user);
    }

    @Override
    public Map<String, Object> getForm(Map<String, Object> params) {
        Map<String, Object> apidatas = new HashMap<>(16);

        Long id = null;
        if (Objects.nonNull(params.get("id"))) {
            id =Long.valueOf(Util.null2String(params.get("id")));
        }
        WelfareTypeEnum welfareTypeEnum = (WelfareTypeEnum)params.get("welfareTypeEnum");
        InsuranceSchemeFormVO form = getForm(id, welfareTypeEnum);
        apidatas.put("form",form);
        //记录操作日志
        InsuranceSchemeDTO schemeBatch = form.getSchemeBatch();
        LoggerContext loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(schemeBatch.getId()));
        loggerContext.setTargetName(schemeBatch.getSchemeName());
        loggerContext.setOperateType(OperateTypeEnum.READ.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "查看福利方案明细"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "查看福利方案明细") + ": " + schemeBatch.getSchemeName());
        SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
        return apidatas;
    }

    @Override
    public Map<String, Object> insertScheme(Map<String, Object> params) {
//        return commandExecutor.execute(new SISchemeInsertCmd(params, user));
        Map<String, Object> apidatas = new HashMap<String, Object>(16);
        InsuranceSchemeReqParam insuranceSchemeReqParam = (InsuranceSchemeReqParam) params.get("insuranceSchemeReqParam");
//        siSchemeBiz.save(insuranceSchemeReqParam, (long) user.getUID());
        save(insuranceSchemeReqParam, (long) user.getUID());
        return apidatas;
    }

    @Override
    public String update(Map<String, Object> params) {
//        return commandExecutor.execute(new SISchemeUpdateCmd(params, user));
        Map<String, Object> apidatas = new HashMap<String, Object>(16);
        InsuranceSchemeReqParam insuranceSchemeReqParam = (InsuranceSchemeReqParam) params.get("insuranceSchemeReqParam");
//        siSchemeBiz.update(insuranceSchemeReqParam, (long) user.getUID());
        return update(insuranceSchemeReqParam, (long) user.getUID());
    }

    @Override
    public Map<String, Object> delete(Map<String, Object> params) {
//        return commandExecutor.execute(new SISchemeDeleteCmd(params, user));
        Map<String, Object> apidatas = new HashMap<String, Object>(16);
        Collection<Long> ids = (Collection<Long>)params.get("ids");
        if (CollectionUtils.isEmpty(ids)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"参数错误"));
        }
        //校验带上类型
        int welfareTypeId = (Integer) params.get("welfareTypeId");
        if(WelfareTypeEnum.SOCIAL_SECURITY.getValue() == welfareTypeId){
//            int num = siSchemeBiz.checkBeforeDeleteSocialscheme(params);
            int num = checkBeforeDeleteSocialscheme(params);
            if (num > 0){
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"该社保方案已被使用"));
            }
        }
        if(WelfareTypeEnum.ACCUMULATION_FUND.getValue() == welfareTypeId){
//            int accumulationfundNum = siSchemeBiz.checkBeforeDeleteAccumulationfund(params);
            int accumulationfundNum = checkBeforeDeleteAccumulationfund(params);
            if (accumulationfundNum > 0){
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"该公积金方案已被使用"));
            }
        }
        if(WelfareTypeEnum.OTHER.getValue() == welfareTypeId){
//            int otherschemeNum = siSchemeBiz.checkBeforeDeleteOtherscheme(params);
            int otherschemeNum = checkBeforeDeleteOtherscheme(params);
            if (otherschemeNum > 0){
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"该其他福利方案已被使用"));
            }
        }

//        int billNum = siSchemeBiz.checkBeforeDeleteBill(params,welfareTypeId);
        int billNum = checkBeforeDeleteBill(params,welfareTypeId);
        if (billNum > 0){
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"该福利方案已被核算"));
        }
//        siSchemeBiz.deleteSocialscheme(params);
        deleteSocialscheme(params);

        return apidatas;
    }

    @Override
    public Map<String, Object> copyScheme(Map<String, Object> params) {
//        return commandExecutor.execute(new SISchemeCopyCmd(params, user));
        Map<String, Object> apidatas = new HashMap<String, Object>(16);
        Long id = (Long) params.get("id");
        String schemeName = Util.null2String(params.get("schemeName"));
//        siSchemeBiz.copy(id,schemeName,(long) user.getUID());
        copy(id,schemeName,(long) user.getUID());
        return apidatas;
    }

    @Override
    public List<InsuranceSchemeDetailPO> queryListByInsuranceIdIsPayment(Long insuranceId, Integer isPayment) {
//        return new SISchemeBiz().queryListByInsuranceIdIsPayment(insuranceId, isPayment);

        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOList = getInsuranceSchemeDetailMapper().queryListByInsuranceIdIsPayment(insuranceId, isPayment);
        encryptUtil.decryptList(insuranceSchemeDetailPOList, InsuranceSchemeDetailPO.class);
        return insuranceSchemeDetailPOList;
    }

    @Override
    public Map<String, Object> listPage(Map<String, Object> params) {
//        return commandExecutor.execute(new SISchemeListCmd(params, user));
        SalaryWeaTable<SISchemeTableVO> table = new SalaryWeaTable<>(user,SISchemeTableVO.class);
        String sqlWhere = buildSqlWhere(params);
        table.setSqlwhere(sqlWhere);

        WeaResultMsg result = new WeaResultMsg(false);
        result.putAll(table.makeDataResult());
        result.success();
        return result.getResultMap();
    }

    private String buildSqlWhere(Map<String, Object> params) {
        String sqlWhere = "where a.id = b.primary_id and b.insurance_id = c.id and a.delete_Type = 0";
        Integer welfareType = (Integer)params.get("welfareType");
        if (Objects.nonNull(welfareType)){
            sqlWhere += " and a.welfare_type ="+welfareType;
        }
        return sqlWhere;
    }

    @Override
    public Map<Long, String> getSchemeIdNameMap() {
        Map<Long, String> result = new HashMap<>();
        List<InsuranceSchemePO> insuranceSchemePOS = getInsuranceSchemeMapper().listAll();
        if (CollectionUtils.isNotEmpty(insuranceSchemePOS)) {
            result = insuranceSchemePOS.stream().collect(Collectors.toMap(InsuranceSchemePO::getId, InsuranceSchemePO::getSchemeName));
        }
        return result;
    }

    @Override
    public PageInfo<InsuranceSchemeListDTO> list(InsuranceSchemeParam queryParam) {
        SalaryAssert.notNull(queryParam.getWelfareTypeEnum(), SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
        queryParam.setWelfareType(queryParam.getWelfareTypeEnum().getValue());
        if (queryParam.getPaymentTypeEnum() != null) {
            queryParam.setPaymentType(queryParam.getPaymentTypeEnum().getValue());
        }
        List<InsuranceSchemePO> insuranceSchemePOS = getInsuranceSchemeMapper().list(queryParam);;
        TaxAgentQueryParam param = TaxAgentQueryParam.builder().build();
        param.setFilterType(AuthFilterTypeEnum.QUERY_DATA);
        Collection<TaxAgentPO> taxAgentList = getTaxAgentService().listAuth(param);
        List<Long> authTaxAgentIds = SalaryEntityUtil.properties(taxAgentList, TaxAgentPO::getId, Collectors.toList());
        insuranceSchemePOS = insuranceSchemePOS.stream().filter(po -> {
            String taxAgentIdsStr = po.getTaxAgentIds();
            List<Long> taxAgentIds = new ArrayList<>();
            if (StringUtils.isNotBlank(taxAgentIdsStr)) {
                taxAgentIds = Arrays.stream(taxAgentIdsStr.split(",")).map(Long::valueOf).collect(Collectors.toList());
            }
            return StringUtils.isBlank(po.getSharedType()) || SharedTypeEnum.PUBLIC.getValue().equals(po.getSharedType()) || (SharedTypeEnum.PRIVATE.getValue().equals(po.getSharedType()) && SalaryEntityUtil.judgeIntersection(authTaxAgentIds, taxAgentIds));
        }).collect(Collectors.toList());

        PageInfo<InsuranceSchemeListDTO> dtoPage = new PageInfo<>(InsuranceSchemeListDTO.class);
        dtoPage.setPageNum(queryParam.getCurrent());
        dtoPage.setPageSize(queryParam.getPageSize());
        dtoPage.setTotal(insuranceSchemePOS.size());
        //分页
        insuranceSchemePOS = SalaryPageUtil.subList(queryParam.getCurrent(), queryParam.getPageSize(), insuranceSchemePOS);
        List<InsuranceSchemeListDTO> collect = insuranceSchemePOS.stream().map(item -> InsuranceSchemeListDTO.builder().id(item.getId()).paymentType(SalaryI18nUtil.getI18nLabel(buildPaymentTypeEnum(item.getPaymentType()).getLabelId(), buildPaymentTypeEnum(item.getPaymentType()).getDefaultLabel())).schemeName(item.getSchemeName()).paymentArea(item.getPaymentArea()).paymentScope(buildPaymentScope(item.getId())).remarks(item.getRemarks()).build()).collect(Collectors.toList());
        dtoPage.setList(collect);
        return dtoPage;
    }

    @Override
    public List<InsuranceArchivesEmployeePO> listPageEmployeePOS(InsuranceArchivesListParam param) {
        long currentEmployeeId = user.getUID();
        //排序配置
        OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
        param.setOrderRule(orderRule);

        List<InsuranceArchivesEmployeePO> list = getSocialSchemeMapper().queryEmployeeList(param);
        list = getAuthService(user).auth(list, AuthFilterTypeEnum.QUERY_DATA, InsuranceArchivesEmployeePO.class);
        return list;
    }

    @Override
    public List<Map<String, Object>> buildTableData(List<InsuranceArchivesEmployeePO> insuranceArchivesEmployeePOS) {
//        boolean welBaseDiffSign = siArchivesBiz.isDiffWelBase();
        boolean welBaseDiffSign = getSIArchivesService(user).isDiffWelBase();
        List<Map<String, Object>> records = new ArrayList<>();
        List<TaxAgentPO> taxAgentPOS = getTaxAgentMapper().listAll();
        Map<Long, TaxAgentPO> longTaxAgentPOMap = SalaryEntityUtil.convert2Map(taxAgentPOS, TaxAgentPO::getId);
        List<Long> employeeIds = insuranceArchivesEmployeePOS.stream().map(InsuranceArchivesEmployeePO::getEmployeeId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(employeeIds)) {
            return records;
        }
        List<InsuranceArchivesSocialSchemePO> socialList = new ArrayList<>();
        List<InsuranceArchivesFundSchemePO> fundList = new ArrayList<>();
        List<InsuranceArchivesOtherSchemePO> otherList = new ArrayList<>();

        for (int i = 0; i < employeeIds.size(); i += 1000) {
            int end = i + 1000;
            if (i + 1000 >= employeeIds.size()) {
                end = employeeIds.size();
            }
            List<Long> ids = employeeIds.subList(i, end);
            socialList.addAll(encryptUtil.decryptList(getSIArchivesService(user).getSocialByEmployeeIds(ids), InsuranceArchivesSocialSchemePO.class));
            fundList.addAll(encryptUtil.decryptList(getSIArchivesService(user).getFundByEmployeeIds(ids), InsuranceArchivesFundSchemePO.class));
            otherList.addAll(encryptUtil.decryptList(getSIArchivesService(user).getOtherByEmployeeIds(ids), InsuranceArchivesOtherSchemePO.class));
        }
        Map<String, InsuranceArchivesSocialSchemePO> socialSchemePOMap = SalaryEntityUtil.convert2Map(socialList, k -> k.getPaymentOrganization() + "-" + k.getEmployeeId());
        Map<String, InsuranceArchivesFundSchemePO> fundSchemePOMap = SalaryEntityUtil.convert2Map(fundList, k -> k.getPaymentOrganization() + "-" + k.getEmployeeId());
        Map<String, InsuranceArchivesOtherSchemePO> otherSchemePOMap = SalaryEntityUtil.convert2Map(otherList, k -> k.getPaymentOrganization() + "-" + k.getEmployeeId());

        insuranceArchivesEmployeePOS.forEach(item -> {
            InsuranceArchivesSocialSchemePO socialItem = socialSchemePOMap.get(item.getPaymentOrganization() + "-" + item.getEmployeeId());
            InsuranceArchivesFundSchemePO fundItem = fundSchemePOMap.get(item.getPaymentOrganization() + "-" + item.getEmployeeId());
            InsuranceArchivesOtherSchemePO otherItem = otherSchemePOMap.get(item.getPaymentOrganization() + "-" + item.getEmployeeId());
            Map<String, Object> map = new HashMap<>();
            map.put("employeeName", item.getUserName());
            map.put("employeeId", item.getEmployeeId());
            map.put("subcompanyName", item.getSubcompanyName());
            map.put("departmentName", item.getDepartmentName());
            map.put("departmentId", item.getDepartmentId());
            map.put("jobNum", item.getJobNum());
            map.put("idNo", item.getIdNo());
            map.put("paymentOrganizationName", longTaxAgentPOMap.get(item.getPaymentOrganization()) != null ? longTaxAgentPOMap.get(item.getPaymentOrganization()).getName() : "");
            map.put("mobile", item.getTelephone());
            map.put("status", item.getUserStatus() == null ? "" : UserStatusEnum.getDefaultLabelByValue(item.getUserStatus()));
            if (socialItem != null) {
                map.put("socialName", getSiSchemeService().querySchemeName(socialItem.getSocialSchemeId()));
                Map<String, Object> socialJson = JSON.parseObject(socialItem.getSocialPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (welBaseDiffSign) {
                    if (socialJson != null) {
                        //查询该福利方案下开启缴纳的福利项
//                        List<Long> insuranceIdList = siArchivesBiz.payInsuranceIds(socialItem.getSocialSchemeId(), PaymentScopeEnum.SCOPE_PERSON.getValue());
                        List<Long> insuranceIdList = getSIArchivesService(user).payInsuranceIds(socialItem.getSocialSchemeId(), PaymentScopeEnum.SCOPE_PERSON.getValue());
                        socialJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k + "per", v);
                            }
                        });
                    }
                    Map<String, Object> socialComJson = JSON.parseObject(socialItem.getSocialPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (socialComJson != null) {
                        //查询该福利方案下开启缴纳的福利项
//                        List<Long> insuranceIdList = siArchivesBiz.payInsuranceIds(socialItem.getSocialSchemeId(),PaymentScopeEnum.SCOPE_COMPANY.getValue());
                        List<Long> insuranceIdList = getSIArchivesService(user).payInsuranceIds(socialItem.getSocialSchemeId(),PaymentScopeEnum.SCOPE_COMPANY.getValue());
                        socialComJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k + "com", v);
                            }
                        });
                    }
                } else {
                    if (socialJson != null) {
                        //查询该福利方案下开启缴纳的福利项
                        List<Long> insuranceIdList = payInsuranceIds(socialItem.getSocialSchemeId());
                        socialJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k, v);
                            }
                        });
                    }
                }
                map.put("socialAccount", socialItem.getSocialAccount());
                map.put("socialStartTime", socialItem.getSocialStartTime());
                map.put("socialEndTime", socialItem.getSocialEndTime());
            }
            if (fundItem != null) {
                map.put("fundName", getSiSchemeService().querySchemeName(fundItem.getFundSchemeId()));
                map.put("fundAccount", fundItem.getFundAccount());
                Map<String, Object> fundJson = JSON.parseObject(fundItem.getFundPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (welBaseDiffSign) {
                    if (fundJson != null) {
                        //查询该福利方案下开启缴纳的福利项
//                        List<Long> insuranceIdList = siArchivesBiz.payInsuranceIds(fundItem.getFundSchemeId(),PaymentScopeEnum.SCOPE_PERSON.getValue());
                        List<Long> insuranceIdList = getSIArchivesService(user).payInsuranceIds(fundItem.getFundSchemeId(),PaymentScopeEnum.SCOPE_PERSON.getValue());
                        fundJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k + "per", v);
                            }
                        });
                    }
                    Map<String, Object> fundComJson = JSON.parseObject(fundItem.getFundPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (fundComJson != null) {
                        //查询该福利方案下开启缴纳的福利项
//                        List<Long> insuranceIdList = siArchivesBiz.payInsuranceIds(fundItem.getFundSchemeId(),PaymentScopeEnum.SCOPE_COMPANY.getValue());
                        List<Long> insuranceIdList = getSIArchivesService(user).payInsuranceIds(fundItem.getFundSchemeId(),PaymentScopeEnum.SCOPE_COMPANY.getValue());
                        fundComJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k + "com", v);
                            }
                        });
                    }
                } else {
                    if (fundJson != null) {
                        //查询该福利方案下开启缴纳的福利项
                        List<Long> insuranceIdList = payInsuranceIds(fundItem.getFundSchemeId());
                        fundJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k, v);
                            }
                        });
                    }
                }
                map.put("supplementFundAccount", fundItem.getSupplementFundAccount());
                map.put("fundStartTime", fundItem.getFundStartTime());
                map.put("fundEndTime", fundItem.getFundEndTime());

            }
            if (otherItem != null) {
                map.put("otherName", getSiSchemeService().querySchemeName(otherItem.getOtherSchemeId()));
                Map<String, Object> otherJson = JSON.parseObject(otherItem.getOtherPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (welBaseDiffSign) {
                    if (otherJson != null) {
                        //查询该福利方案下开启缴纳的福利项
//                        List<Long> insuranceIdList = siArchivesBiz.payInsuranceIds(otherItem.getOtherSchemeId(),PaymentScopeEnum.SCOPE_PERSON.getValue());
                        List<Long> insuranceIdList = getSIArchivesService(user).payInsuranceIds(otherItem.getOtherSchemeId(),PaymentScopeEnum.SCOPE_PERSON.getValue());
                        otherJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k + "per", v);
                            }
                        });
                    }
                    Map<String, Object> otherComJson = JSON.parseObject(otherItem.getOtherPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (otherComJson != null) {
                        //查询该福利方案下开启缴纳的福利项
//                        List<Long> insuranceIdList = siArchivesBiz.payInsuranceIds(otherItem.getOtherSchemeId(),PaymentScopeEnum.SCOPE_COMPANY.getValue());
                        List<Long> insuranceIdList = getSIArchivesService(user).payInsuranceIds(otherItem.getOtherSchemeId(),PaymentScopeEnum.SCOPE_COMPANY.getValue());
                        otherComJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k + "com", v);
                            }
                        });
                    }
                } else {
                    if (otherJson != null) {
                        //查询该福利方案下开启缴纳的福利项
                        List<Long> insuranceIdList = payInsuranceIds(otherItem.getOtherSchemeId());
                        otherJson.forEach((k, v) -> {
                            if (insuranceIdList.contains(Long.valueOf(k))) {
                                map.put(k, v);
                            }
                        });
                    }
                }
                map.put("otherStartTime", otherItem.getOtherStartTime());
                map.put("otherEndTime", otherItem.getOtherEndTime());
            }
            records.add(map);
        });
        return records;
    }

    public List<Long> payInsuranceIds(Long socialSchemeId) {
        //查询该福利方案下开启缴纳的福利项
        List<InsuranceSchemeDetailPO> detailPOS = getInsuranceSchemeDetailMapper().queryListBySchemeId(socialSchemeId);
        List<Long> insuranceIdList = new ArrayList<>();
        if (detailPOS != null && detailPOS.size() > 0) {
            //开启缴纳的
            insuranceIdList = detailPOS.stream().filter(f -> f.getIsPayment().equals(IsPaymentEnum.YES.getValue())).map(InsuranceSchemeDetailPO::getInsuranceId).collect(Collectors.toList());
        }
        return insuranceIdList;
    }

    @Override
    public XSSFWorkbook export(InsuranceArchivesListParam param) {
        InsuranceArchivesListParam request = InsuranceArchivesListParam.builder().build();
        if (param.getHireDate() != null && param.getHireDate().length == 2) {
            param.setHiredateStart(param.getHireDate()[0]);
            param.setHiredateEnd(param.getHireDate()[1]);
        }
        if (param.getDimissionDate() != null && param.getDimissionDate().length == 2) {
            param.setDimissionDateStart(param.getDimissionDate()[0]);
            param.setDimissionDateEnd(param.getDimissionDate()[1]);
        }
        if (Objects.equals("fromQuickSearch", param.getDataSource())) {
            request.setStatuses(param.getStatuses());
            request.setKeyword(param.getUserName());
        } else {
            request = param;
        }
        request.setPageSize(null);
        request.setStartNum(null);
        List<InsuranceArchivesEmployeePO> insuranceArchivesEmployeePOS = listPageEmployeePOS(request);
        if (insuranceArchivesEmployeePOS == null) {
            insuranceArchivesEmployeePOS = new ArrayList<>();
        }
        SalaryI18nUtil.i18nList(insuranceArchivesEmployeePOS);
        List<Map<String, Object>> records = buildTableData(insuranceArchivesEmployeePOS);
        List<WeaTableColumn> columns = buildWeaTableColumns(insuranceArchivesEmployeePOS, (long) user.getUID());

        //工作簿list


        String sheetName;
        //表头
        if (param.getRunStatuses().size() > 0) {
            if (param.getRunStatuses().contains(EmployeeStatusEnum.STAY_ADD.getValue()) && param.getRunStatuses().size() == 1) {
                sheetName = SalaryI18nUtil.getI18nLabel(85368, "社保福利档案导出" + "-" + EmployeeStatusEnum.STAY_ADD.getDefaultLabel());
            } else if (param.getRunStatuses().contains(EmployeeStatusEnum.PAYING.getValue()) && param.getRunStatuses().contains(EmployeeStatusEnum.STAY_DEL.getValue()) && param.getRunStatuses().size() == 2) {
                sheetName = SalaryI18nUtil.getI18nLabel(85368, "社保福利档案导出" + "-" + "在缴员工");
            } else if (param.getRunStatuses().contains(EmployeeStatusEnum.STAY_DEL.getValue()) && param.getRunStatuses().size() == 1) {
                sheetName = SalaryI18nUtil.getI18nLabel(85368, "社保福利档案导出" + "-" + EmployeeStatusEnum.STAY_DEL.getDefaultLabel());
            } else if (param.getRunStatuses().contains(EmployeeStatusEnum.STOP_PAYMENT_FROM_ADD.getValue()) && param.getRunStatuses().contains(EmployeeStatusEnum.STOP_PAYMENT_FROM_DEL.getValue()) && param.getRunStatuses().size() == 2) {
                sheetName = SalaryI18nUtil.getI18nLabel(85368, "社保福利档案导出" + "-" + "停缴员工");
            } else {
                sheetName = SalaryI18nUtil.getI18nLabel(85368, "社保福利档案导出");
            }
        } else {
            sheetName = SalaryI18nUtil.getI18nLabel(85368, "社保福利档案导出");
        }

        //工作簿数据
        List<List<Object>> rows = new LinkedList<>();
        List<Object> collect = columns.stream().map(WeaTableColumn::getText).collect(Collectors.toList());
        rows.add(collect);
        for (Map<String, Object> recordData : records) {
            List<Object> row = new LinkedList<>();
            for (WeaTableColumn column : columns) {
                try {
                    Object o = recordData.get(column.getColumn());
                    if (column.getText().contains("申报基数")  && StringUtils.isNotBlank(o.toString())) {
                        row.add(new BigDecimal(o.toString()));
                    } else {
                        row.add(o.toString());
                    }
                } catch (Exception e) {
                    row.add("");
                }
            }
            rows.add(row);
        }
        //记录操作日志
        LoggerContext loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setOperateType(OperateTypeEnum.EXCEL_EXPORT.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "福利档案导出"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利档案导出"));
        SalaryElogConfig.siArchivesLoggerTemplate.write(loggerContext);
        //获取excel
        return ExcelUtilPlus.genWorkbookV2(rows, sheetName);
    }


    public PaymentTypeEnum buildPaymentTypeEnum(Integer value) {
        return SalaryEnumUtil.enumMatchByValue(value, PaymentTypeEnum.values(), PaymentTypeEnum.class);
    }


    /**
     * 组装社保福利方案列表页【缴纳范围】
     * 1、到福利方案明细表查询该方案id下面有哪些福利
     * 2、去重（福利是分个人和公司的，明细表中查询出来的福利id会重复）
     * 3、根据查询出来的福利id，去福利表里面查询福利的名称
     * 4、组装，以“、”分割
     *
     * @param id 福利方案主表id
     * @return result
     */
    public String buildPaymentScope(Long id) {
        List<String> collect = queryInsuranceSchemeDetailList(id).stream().map(InsuranceSchemeDetailPO::getInsuranceId).distinct().collect(Collectors.toList()).stream().map(this::queryInsuranceName).collect(Collectors.toList());
        return StringUtils.join(collect, "、");
    }

    public Collection<InsuranceSchemeDetailPO> queryInsuranceSchemeDetailList(Long id) {
        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = getInsuranceSchemeDetailMapper().queryInsuranceSchemeDetailList(id, IsPaymentEnum.YES.getValue());
        return encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
    }

    public String queryInsuranceName(Long id) {
        ICategoryPO insuranceCategoryPO = getICategoryMapper().getById(id);
        return insuranceCategoryPO == null ? "" : Objects.isNull(insuranceCategoryPO.getInsuranceName()) ? "" : insuranceCategoryPO.getInsuranceName();
    }


    @Override
    public String querySchemeName(Long schemeId) {
        if (schemeId == null) {
            return "";
        }
        InsuranceSchemePO insuranceSchemePO = getInsuranceSchemeMapper().getById(schemeId);
        if (insuranceSchemePO == null) {
            return "";
        } else {
            return insuranceSchemePO.getSchemeName();
        }
    }


    @Override
    public List<WeaTableColumn> buildWeaTableColumns(List<InsuranceArchivesEmployeePO> insuranceArchivesEmployeePOS, Long employeeId) {
        Map<Integer, Map<String, String>> titleMap = buildColumnTitle(insuranceArchivesEmployeePOS, employeeId);
        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn nameColumn = new WeaTableColumn("100px", SalaryI18nUtil.getI18nLabel(85429, "姓名"), "employeeName");
        nameColumn.setFixed("left");
        list.add(nameColumn);
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(93910, "个税扣缴义务人"), "paymentOrganizationName"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(0, "分部"), "subcompanyName"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(86185, "部门"), "departmentName"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(86186, "手机号"), "mobile"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(86187, "员工状态"), "status"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(1933, "工号"), "jobNum"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(1933, "证件号码"), "idNo"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"), "socialName"));
        titleMap.get(WelfareTypeEnum.SOCIAL_SECURITY.getValue()).forEach((k, v) -> list.add(new WeaTableColumn("150px", v, k)));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91324, "社保账号"), "socialAccount"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91319, "社保起始缴纳月"), "socialStartTime"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91320, "社保最后缴纳月"), "socialEndTime"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"), "fundName"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91486, "公积金账号"), "fundAccount"));
        titleMap.get(WelfareTypeEnum.ACCUMULATION_FUND.getValue()).forEach((k, v) -> list.add(new WeaTableColumn("150px", v, k)));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91487, "补充公积金账号"), "supplementFundAccount"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91483, "公积金起始缴纳月"), "fundStartTime"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91484, "公积金最后缴纳月"), "fundEndTime"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称"), "otherName"));
        titleMap.get(WelfareTypeEnum.OTHER.getValue()).forEach((k, v) -> list.add(new WeaTableColumn("150px", v, k)));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91490, "其他福利起始缴纳月"), "otherStartTime"));
        list.add(new WeaTableColumn("150px", SalaryI18nUtil.getI18nLabel(91494, "其他福利最后缴纳月"), "otherEndTime"));
        return list;
    }


    public Map<Integer, Map<String, String>> buildColumnTitle(List<InsuranceArchivesEmployeePO> insuranceArchivesEmployeePOS, Long employeeId) {
//        boolean welBaseDiffSign = siArchivesBiz.isDiffWelBase();
        boolean welBaseDiffSign = getSIArchivesService(user).isDiffWelBase();

        Map<Integer, Map<String, String>> result = new HashMap<>();
        Set<String> socialSet = new HashSet<>();
        Set<String> fundSet = new HashSet<>();
        Set<String> otherSet = new HashSet<>();

        Set<String> socialComSet = new HashSet<>();
        Set<String> fundComSet = new HashSet<>();
        Set<String> otherComSet = new HashSet<>();

        insuranceArchivesEmployeePOS.forEach(item -> {
            List<InsuranceArchivesSocialSchemePO> socialByEmployeeId = getSIArchivesService(user).getSocialByEmployeeIds(new ArrayList<Long>() {{
                add(item.getEmployeeId());
            }});
            // 过滤义务人
            socialByEmployeeId = socialByEmployeeId.stream().filter(s -> s.getPaymentOrganization().equals(item.getPaymentOrganization())).collect(Collectors.toList());
            encryptUtil.decryptList(socialByEmployeeId, InsuranceArchivesSocialSchemePO.class);
            InsuranceArchivesSocialSchemePO socialItem = null;
            if (socialByEmployeeId.size() > 0) {
                socialItem = socialByEmployeeId.get(0);
            }
            InsuranceArchivesFundSchemePO fundItem = null;

            List<InsuranceArchivesFundSchemePO> fundByEmployeeId = getSIArchivesService(user).getFundByEmployeeIds(new ArrayList<Long>() {{
                add(item.getEmployeeId());
            }});
            // 过滤义务人
            fundByEmployeeId = fundByEmployeeId.stream().filter(f -> f.getPaymentOrganization().equals(item.getPaymentOrganization())).collect(Collectors.toList());
            encryptUtil.decryptList(fundByEmployeeId, InsuranceArchivesFundSchemePO.class);

            if (fundByEmployeeId.size() > 0) {
                fundItem = fundByEmployeeId.get(0);
            }
            InsuranceArchivesOtherSchemePO otherItem = null;

            List<InsuranceArchivesOtherSchemePO> otherByEmployeeId = getSIArchivesService(user).getOtherByEmployeeIds(new ArrayList<Long>() {{
                add(item.getEmployeeId());
            }});
            otherByEmployeeId = otherByEmployeeId.stream().filter(o -> o.getPaymentOrganization().equals(item.getPaymentOrganization())).collect(Collectors.toList());
            encryptUtil.decryptList(otherByEmployeeId, InsuranceArchivesOtherSchemePO.class);
            if (otherByEmployeeId.size() > 0) {
                otherItem = otherByEmployeeId.get(0);
            }

            if (socialItem != null) {
                Map<String, Object> socialJson = JSON.parseObject(socialItem.getSocialPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (socialJson != null) {
                    socialJson.forEach((k, v) -> socialSet.add(k));
                }
                //如果需要区分个人和公司福利基数
                if (welBaseDiffSign) {
                    Map<String, Object> socialComJson = JSON.parseObject(socialItem.getSocialPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (socialComJson != null) {
                        socialComJson.forEach((k, v) -> socialComSet.add(k));
                    }
                }
            }
            if (fundItem != null) {
                Map<String, Object> fundJson = JSON.parseObject(fundItem.getFundPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (fundJson != null) {
                    fundJson.forEach((k, v) -> fundSet.add(k));
                }
                //如果需要区分个人和公司福利基数
                if (welBaseDiffSign) {
                    Map<String, Object> fundComJson = JSON.parseObject(fundItem.getFundPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (fundComJson != null) {
                        fundComJson.forEach((k, v) -> fundComSet.add(k));
                    }
                }
            }
            if (otherItem != null) {
                Map<String, Object> otherJson = JSON.parseObject(otherItem.getOtherPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (otherJson != null) {
                    otherJson.forEach((k, v) -> otherSet.add(k));
                }
                //如果需要区分个人和公司福利基数
                if (welBaseDiffSign) {
                    Map<String, Object> otherComJson = JSON.parseObject(otherItem.getOtherPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (otherComJson != null) {
                        otherComJson.forEach((k, v) -> otherComSet.add(k));
                    }
                }
            }
        });
        Map<String, String> socialMap = new HashMap<>();
        Map<String, String> socialComMap = new HashMap<>();
        Map<Long, ICategoryPO> socialCollect = new HashMap<>();
        Map<Long, ICategoryPO> customSocial = getICategoryMapper().listByWelfareType(WelfareTypeEnum.SOCIAL_SECURITY.getValue(), null).stream().collect(Collectors.toMap(ICategoryPO::getId, Function.identity()));

        Map<Long, ICategoryPO> sysSocial = getICategoryMapper().listByWelfareType(WelfareTypeEnum.SOCIAL_SECURITY.getValue(), DataTypeEnum.SYSTEM.getValue()).stream().collect(Collectors.toMap(ICategoryPO::getId, Function.identity()));
        socialCollect.putAll(customSocial);
        socialCollect.putAll(sysSocial);
        if (welBaseDiffSign) {
            socialSet.forEach(item -> {
                if (socialCollect.containsKey(Long.valueOf(item))) {
                    socialMap.put(item + "per", socialCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数")  + SalaryI18nUtil.getI18nLabel(0,"个人"));
                }
            });
            socialComSet.forEach(item -> {
                if (socialCollect.containsKey(Long.valueOf(item))) {
                    socialComMap.put(item + "com", socialCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0,"单位"));
                }
            });
        } else {
            socialSet.forEach(item -> {
                if (socialCollect.containsKey(Long.valueOf(item))) {
                    socialMap.put(item, socialCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                }
            });
        }
        Map<String, String> fundMap = new HashMap<>();
        Map<String, String> fundComMap = new HashMap<>();
        Map<Long, ICategoryPO> fundCollect = new HashMap<>();
        Map<Long, ICategoryPO> customFund = getICategoryMapper().listByWelfareType(WelfareTypeEnum.ACCUMULATION_FUND.getValue(), null).stream().collect(Collectors.toMap(ICategoryPO::getId, Function.identity()));
        Map<Long, ICategoryPO> sysFund = getICategoryMapper().listByWelfareType(WelfareTypeEnum.ACCUMULATION_FUND.getValue(), DataTypeEnum.SYSTEM.getValue()).stream().collect(Collectors.toMap(ICategoryPO::getId, Function.identity()));
        fundCollect.putAll(customFund);
        fundCollect.putAll(sysFund);
        if (welBaseDiffSign) {
            fundSet.forEach(item -> {
                if (fundCollect.containsKey(Long.valueOf(item))) {
                    fundMap.put(item + "per", fundCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0,"个人"));
                }
            });
            fundComSet.forEach(item -> {
                if (fundCollect.containsKey(Long.valueOf(item))) {
                    fundComMap.put(item + "com", fundCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0,"单位"));
                }
            });
        } else {
            fundSet.forEach(item -> {
                if (fundCollect.containsKey(Long.valueOf(item))) {
                    fundMap.put(item, fundCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                }
            });
        }
        Map<String, String> otherMap = new HashMap<>();
        Map<String, String> otherComMap = new HashMap<>();
        Map<Long, ICategoryPO> otherCollect = new HashMap<>();
        Map<Long, ICategoryPO> customOther = getICategoryMapper().listByWelfareType(WelfareTypeEnum.OTHER.getValue(), null).stream().collect(Collectors.toMap(ICategoryPO::getId, Function.identity()));
        Map<Long, ICategoryPO> sysOther = getICategoryMapper().listByWelfareType(WelfareTypeEnum.OTHER.getValue(), DataTypeEnum.SYSTEM.getValue()).stream().collect(Collectors.toMap(ICategoryPO::getId, Function.identity()));
        otherCollect.putAll(customOther);
        otherCollect.putAll(sysOther);
        if (welBaseDiffSign) {
            otherSet.forEach(item -> {
                if (otherCollect.containsKey(Long.valueOf(item))) {
                    otherMap.put(item + "per", otherCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0,"个人"));
                }
            });
            otherComSet.forEach(item -> {
                if (otherCollect.containsKey(Long.valueOf(item))) {
                    otherComMap.put(item + "com", otherCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0,"单位"));
                }
            });
        } else {
            otherSet.forEach(item -> {
                if (otherCollect.containsKey(Long.valueOf(item))) {
                    otherMap.put(item, otherCollect.get(Long.valueOf(item)).getInsuranceName() + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                }
            });
        }

        // map根据key排序
        LinkedHashMap<String, String> socialMapWithAscKey = socialMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new));
        LinkedHashMap<String, String> fundMapWithAscKey = fundMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new));
        LinkedHashMap<String, String> otherMapWithAscKey = otherMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new));
        if (welBaseDiffSign) {
            LinkedHashMap<String, String> socialComMapWithAscKey = socialComMap.entrySet().stream()
                    .sorted(Map.Entry.comparingByKey())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                            LinkedHashMap::new));
            LinkedHashMap<String, String> fundComMapWithAscKey = fundComMap.entrySet().stream()
                    .sorted(Map.Entry.comparingByKey())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                            LinkedHashMap::new));
            LinkedHashMap<String, String> otherComMapWithAscKey = otherComMap.entrySet().stream()
                    .sorted(Map.Entry.comparingByKey())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                            LinkedHashMap::new));
            socialMapWithAscKey.putAll(socialComMapWithAscKey);
            fundMapWithAscKey.putAll(fundComMapWithAscKey);
            otherMapWithAscKey.putAll(otherComMapWithAscKey);
        }

        result.put(WelfareTypeEnum.SOCIAL_SECURITY.getValue(), socialMapWithAscKey);
        result.put(WelfareTypeEnum.ACCUMULATION_FUND.getValue(), fundMapWithAscKey);
        result.put(WelfareTypeEnum.OTHER.getValue(), otherMapWithAscKey);
        return result;
    }

    /**
     * 导入的数据插入到数据库中
     */
    @Override
    public Map<String, Object> preview(SIArchiveImportParam param) {
        ValidUtil.doValidator(param);
        InputStream fileInputStream = null;
        try {
            fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
            Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
            Map<String, Object> apidatas = new HashMap<String, Object>();
            apidatas.put("headers", ExcelSupport.getSheetHeader(sheet, 0));
            apidatas.put("list", ExcelParseHelper.parse2List(sheet, 1));
            return apidatas;
        } finally {
            IOUtils.closeQuietly(fileInputStream);
        }
    }

    /**
     * 导入的数据插入到数据库中
     */
    @Override
    public Map<String, Object> batchImportEbatch(SIArchiveImportParam param) {
        ValidUtil.doValidator(param);
        param.setProcess(false);

        if (StringUtils.isBlank(param.getRunStatus())) {
            throw new SalaryRunTimeException("福利档案执行状态未在导入条件设置中添加！");
        }
//        List<ExcelSheet> excelSheets = message.getBatchFile().getExcelSheets();
        // 租户key
//        String tenantKey = message.getTenantKey().toLowerCase();EditSIArchiveAction
        //操作员id
        Long creator = (long) user.getUID();
        //获取所有福利类型的id-name结合
        Map<String, Long> schemeNameIdMap = schemeNameIdMap();
        Map<Long, String> welfareMap = welfareMap();
        //分权
        Boolean openDevolution = getTaxAgentService().isOpenDevolution();
        // 获取所有个税扣缴义务人的名称和id的map
        TaxAgentQueryParam build = TaxAgentQueryParam.builder().build();
        build.setFilterType(AuthFilterTypeEnum.ADMIN_DATA);
        Map<String, Long> paymentNameIdMap = getTaxAgentService().listAuth(build).stream().collect(Collectors.toMap(TaxAgentPO::getName, TaxAgentPO::getId));;

        //获取所以个税扣缴义务人树型
        List<TaxAgentManageRangeEmployeeDTO> taxAgentManageRangeEmployeeTree = getTaxAgentService().listTaxAgentAndEmployeeTree();

        // 获取所有人员信息
        List<DataCollectionEmployee> employeeByIds = getSalaryEmployeeService(user).listEmployee();
        int total = 0;

        int index = 0;
        int successCount = 0;
        int errorCount = 0;

        // 待导入数据
        List<InsuranceArchivesAccountPO> insuranceArchivesAccountPOS = new ArrayList<>();

        // 待导入数据
        InputStream fileInputStream = null;
        try {
            fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
            Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
            // 表头
            List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
            // 错误sheet数据
            List<Map<String, Object>> errorData = new LinkedList<>();
            // 错误提示
            List<Map<String, String>> excelComments = new LinkedList<>();

            // 处理数值
            List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 1);
            total = data.size();

            //当前sheel的单行记录
            Map<String, Object> map;
            for (int i = 0; i < data.size(); i++) {
                index += 1;
                map = data.get(i);
                boolean isError;
                List<Map<String, Object>> singleAccount = new ArrayList<>();
                for (int j = 0; j < headers.size(); j++) {
                    //组装单条数据基础数据
                    String key = headers.get(j);
                    if (key == null) {
                        continue;
                    }
                    Map<String, Object> cellData = new HashMap<>();
                    cellData.put(key.toString(), Optional.ofNullable(map.get(key.toString())).orElse("").toString());
                    cellData.put("index", j);
                    singleAccount.add(cellData);
                }

                isError = singleAccountCheck(singleAccount, welfareMap, insuranceArchivesAccountPOS, employeeByIds, excelComments, errorCount + 1, schemeNameIdMap, paymentNameIdMap, creator, i + 2, taxAgentManageRangeEmployeeTree, param);
                if (isError) {
                    errorCount += 1;
                    // 添加错误数据
                    errorData.add(map);
                } else {
                    successCount += 1;
                }
//                salaryBatchService.sendImportRate(message.getBizId(), total, index);
            }

            // 如果sheet包含错误数据
//            if (CollectionUtils.isNotEmpty(errorData)) {
//                salaryBatchService.createErrorExcelSheet(headers, errorData, excelSheet.getName(), excelComments, errorExcelSheets);
//            }

            // 数据入库处理
            handleImportData(insuranceArchivesAccountPOS, param);

            // 发送导入回调信息
//        salaryBatchService.sendImportCallBackInfo(message, successCount, errorCount, errorExcelSheets);

            Map<String, Object> apidatas = new HashMap<String, Object>();
            apidatas.put("successCount", successCount);
            apidatas.put("errorCount", errorCount);
            apidatas.put("errorData", excelComments);
            return apidatas;
        } finally {
            IOUtils.closeQuietly(fileInputStream);
        }
    }


    public Map<String, Long> schemeNameIdMap() {
        Map<String, Long> schemeMap = new HashMap<>();
        List<InsuranceSchemePO> schemeList = getInsuranceSchemeMapper().listAll();
        if (CollectionUtils.isNotEmpty(schemeList)) {
            schemeMap = schemeList.stream().collect(Collectors.toMap(InsuranceSchemePO::getSchemeName, InsuranceSchemePO::getId));
        }
        return schemeMap;
    }

    public Map<Long, String> welfareMap() {
        return getICategoryMapper().listAll().stream().collect(Collectors.toMap(ICategoryPO::getId, ICategoryPO::getInsuranceName));
    }

    private String userStateExchange(String userState) {
        UserStatusEnum[] values = UserStatusEnum.values();
        for (UserStatusEnum value : values) {
            if (value.getValue().equals(Integer.valueOf(userState))) {
                return value.getDefaultLabel() + "";
            }
        }
        return userState;
    }

    public boolean singleAccountCheck(List<Map<String, Object>> singleAccount, Map<Long, String> welfareMap,
                                      List<InsuranceArchivesAccountPO> insuranceArchivesAccountPOS, List<DataCollectionEmployee> employeeByIds,
                                      List<Map<String, String>> excelComments, int i, Map<String, Long> schemeNameIdMap,
                                      Map<String, Long> paymentNameIdMap, Long creator, int index,
                                      List<TaxAgentManageRangeEmployeeDTO> taxAgentManageRangeEmployeeTree, SIArchiveImportParam param) {
        boolean isError = false;
        String runStatus = param.getRunStatus();

//        String userName = (String) singleAccount.get(0).get(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
//        String deparmentName = (String) singleAccount.get(1).get(SalaryI18nUtil.getI18nLabel(86185, "部门"));
//        String mobile = (String) singleAccount.get(2).get(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
//        String userStatus = (String) singleAccount.get(3).get(SalaryI18nUtil.getI18nLabel(86187, "员工状态"));
//        String workcode = (String) singleAccount.get(4).get(SalaryI18nUtil.getI18nLabel(86317, "工号"));

        Map<String, Object> userNameMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(85429, "姓名"));
        Map<String, Object> deparmentNameMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86185, "部门"));
        Map<String, Object> mobileMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86186, "手机号"));
        Map<String, Object> userStatusMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86187, "员工状态"));
        Map<String, Object> workcodeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86317, "工号"));
        Map<String, Object> idNoMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86317, "证件号码"));
        Map<String, Object> employeeIdMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86187, "员工id"));


        String userName = (String) userNameMap.get(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
        String deparmentName = (String) deparmentNameMap.get(SalaryI18nUtil.getI18nLabel(86185, "部门"));
        String mobile = (String) mobileMap.get(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
        String userStatus = (String) userStatusMap.get(SalaryI18nUtil.getI18nLabel(86187, "员工状态"));
        String workcode = (String) workcodeMap.get(SalaryI18nUtil.getI18nLabel(86317, "工号"));
        String idNo = (String) idNoMap.get(SalaryI18nUtil.getI18nLabel(86317, "证件号码"));
        String toAddEmployeeId;
        if (employeeIdMap.isEmpty()) {
            toAddEmployeeId = null;
        } else {
            toAddEmployeeId = employeeIdMap.get(SalaryI18nUtil.getI18nLabel(86187, "员工id")).toString();
        }

        Long addEmployeeId = StringUtils.isNotBlank(toAddEmployeeId) ? Long.valueOf(toAddEmployeeId) : null;

        //查询对于人员信息导入筛选的全局配置
        SalarySysConfPO salarySysConfPO = getSalarySysConfMapper().getOneByCode("matchEmployeeMode");
        String confValue = (salarySysConfPO != null && salarySysConfPO.getConfValue() != null && !"".equals(salarySysConfPO.getConfValue())) ? salarySysConfPO.getConfValue() : "0";

        String rowIndex = "第" + index + "行";
        List<DataCollectionEmployee> employees = new ArrayList<>();
        //当新增数据中包含员工id信息时，直接根据员工id获取员工信息
        if (addEmployeeId == null) {
            //仅在全局人员筛选配置为“0”时，才对用户名、部门名称、手机号有要求
            if (StringUtils.isBlank(userName) && StringUtils.isBlank(deparmentName) && StringUtils.isBlank(mobile) && "0".equals(confValue)) {
                Map<String, String> errorMessageMap = Maps.newHashMap();
                errorMessageMap.put("message", rowIndex + " 用户名、部门名称、手机号" + SalaryI18nUtil.getI18nLabel(100303, "不能同时为空"));
                excelComments.add(errorMessageMap);
                isError = true;
            }
            //筛选导入人员信息可以在人力资源池中匹配到的人员信息
            employees = getSalaryEmployeeService(user).matchImportEmployee(confValue,employeeByIds, userName, deparmentName, mobile, workcode,idNo, null);
        } else {
            employees = employeeByIds.stream().filter(f -> f.getEmployeeId().equals(addEmployeeId)).collect(Collectors.toList());
        }


        if (CollectionUtils.isEmpty(employees)) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + "员工信息不存在");
            excelComments.add(errorMessageMap);
            isError = true;
            return isError;
        } else {
            //含在职和离职，选在职数据
            if (employees.size() > 1) {
                employees = employees.stream()
                        .filter(e -> UserStatusEnum.getNormalStatus().contains(e.getStatus()))
                        .collect(Collectors.toList());
                if (employees.size() != 1) {
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100304, "员工信息不存在或者存在多个员工"));
                    excelComments.add(errorMessageMap);
                    isError = true;
                    return isError;
                }
            }
        }

        Long employeeId = employees.get(0).getEmployeeId();
        InsuranceArchivesAccountPO insuranceArchivesAccountPO = new InsuranceArchivesAccountPO();
        InsuranceArchivesSocialSchemePO insuranceArchivesSocialSchemePO = null;
        InsuranceArchivesFundSchemePO insuranceArchivesFundSchemePO = null;
        InsuranceArchivesOtherSchemePO insuranceArchivesOtherSchemePO = null;

        Map<String, Object> socialMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"));
        Map<String, Object> paymentMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"));
        Map<String, Object> fundMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"));
        Map<String, Object> otherMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称"));
        Map<String, Object> socialStartTimeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91319, "社保起始缴纳月"));
        Map<String, Object> socialEndTimeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91320, "社保最后缴纳月"));
        Map<String, Object> fundStartTimeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91483, "公积金起始缴纳月"));
        Map<String, Object> fundEndTimeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91484, "公积金最后缴纳月"));
        Map<String, Object> otherStartTimeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91490, "其他福利起始缴纳月"));
        Map<String, Object> otherEndTimeMap = findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91494, "其他福利最后缴纳月"));
        if (StringUtils.isBlank((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"))) && StringUtils.isBlank((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"))) && StringUtils.isBlank((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称")))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100312, "社保,公积金,其他福利方案名称不可同时为空"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        //根据导入接口附带的runStatus来区分待增员导入和正在缴纳导入
        if (StringUtils.isNotBlank(runStatus) && runStatus.equals(EmployeeStatusEnum.PAYING.getValue())) {
            if (StringUtils.isBlank((String) socialStartTimeMap.get(SalaryI18nUtil.getI18nLabel(91319, "社保起始缴纳月")))
                    && StringUtils.isBlank((String) fundStartTimeMap.get(SalaryI18nUtil.getI18nLabel(91483, "公积金起始缴纳月")))
                    && StringUtils.isBlank((String) otherStartTimeMap.get(SalaryI18nUtil.getI18nLabel(91490, "其他福利起始缴纳月")))
            ) {
                Map<String, String> errorMessageMap = Maps.newHashMap();
                errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100312, "社保,公积金,其他福利方案起始缴纳月不可同时为空"));
                excelComments.add(errorMessageMap);
                isError = true;
            }
        }
        //社保缴纳组织=个税扣缴义务人
        String paymentOrg = (String) paymentMap.get("个税扣缴义务人");
        if (StringUtils.isBlank(paymentOrg)) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100579, "个税扣缴义务人不允许为空"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else if (!paymentNameIdMap.containsKey(paymentOrg)) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100312, "社保缴纳组织应和个税扣缴义务人名称一致，社保缴纳组织不存在或不在权限范围内"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        if (!isError) {
            Long paymentOrgId = paymentNameIdMap.get(paymentOrg);
            TaxAgentManageRangeEmployeeDTO taxAgentManageRangeEmployeeDTO = taxAgentManageRangeEmployeeTree.stream().filter(tax -> tax.getTaxAgentId().equals(paymentOrgId)).findFirst().get();
            Optional<Long> o = taxAgentManageRangeEmployeeDTO.getEmployeeList().stream().map(TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee::getEmployeeId).filter(e -> e.equals(employeeId)).findFirst();
            if (!o.isPresent()) {
                if (param.isProcess()) {
                    //流程中自动将人员添加进个税扣缴义务人中
                    TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam taxAgentSubAdminRangeTargetParam = new TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam();
                    taxAgentSubAdminRangeTargetParam.setTargetId(employeeId);
                    taxAgentSubAdminRangeTargetParam.setTargetType(TargetTypeEnum.EMPLOYEE);

                    TaxAgentRangeSaveParam taxAgentRangeSaveParam = new TaxAgentRangeSaveParam();
                    taxAgentRangeSaveParam.setTaxAgentId(paymentOrgId);
                    taxAgentRangeSaveParam.setIncludeType(1);
                    taxAgentRangeSaveParam.setEmployeeStatus(Arrays.asList("0", "1", "2", "3", "4", "5", "6"));
                    taxAgentRangeSaveParam.setTargetParams(Collections.singletonList(taxAgentSubAdminRangeTargetParam));
                    taxAgentRangeSaveParam.setSync(true);
                    param.setTaxAgentRanges(Collections.singletonList(taxAgentRangeSaveParam));
                }
            }

        }


        String socialStartMonth = (String) socialStartTimeMap.get(SalaryI18nUtil.getI18nLabel(91319, "社保起始缴纳月"));
        if (StringUtils.isNotBlank(socialStartMonth) && socialStartMonth.length() > 7) {
            socialStartMonth = socialStartMonth.substring(0, 7);
        }
        if (StringUtils.isNotBlank(socialStartMonth) && !SalaryDateUtil.checkYearMonth(socialStartMonth.replace("/",  "-"))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100315, "社保起始缴纳时间格式错误,正确格式为YYYY-MM或者yyyy-MM-dd"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        String socialEndMonth = (String) socialEndTimeMap.get(SalaryI18nUtil.getI18nLabel(91320, "社保最后缴纳月"));
        if (StringUtils.isNotBlank(socialEndMonth) && socialEndMonth.length() > 7) {
            socialEndMonth = socialEndMonth.substring(0, 7);
        }
        if (StringUtils.isNotBlank(socialEndMonth) && !SalaryDateUtil.checkYearMonth(socialEndMonth.replace("/",  "-"))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100316, "社保最后缴纳时间格式错误,正确格式为YYYY-MM或者yyyy-MM-dd"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        String fundStartMonth = (String) fundStartTimeMap.get(SalaryI18nUtil.getI18nLabel(91483, "公积金起始缴纳月"));
        if (StringUtils.isNotBlank(fundStartMonth) && fundStartMonth.length() > 7) {
            fundStartMonth = fundStartMonth.substring(0, 7);
        }
        if (StringUtils.isNotBlank(fundStartMonth) && !SalaryDateUtil.checkYearMonth(fundStartMonth.replace("/",  "-"))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100317, "公积金起始缴纳时间格式错误,正确格式为YYYY-MM或者yyyy-MM-dd"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        String fundEndMonth = (String) fundEndTimeMap.get(SalaryI18nUtil.getI18nLabel(91484, "公积金最后缴纳月"));
        if (StringUtils.isNotBlank(fundEndMonth) && fundEndMonth.length() > 7) {
            fundEndMonth = fundEndMonth.substring(0, 7);
        }
        if (StringUtils.isNotBlank(fundEndMonth) && !SalaryDateUtil.checkYearMonth(fundEndMonth.replace("/",  "-"))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100319, "公积金最后缴纳时间格式错误,正确格式为YYYY-MM或者yyyy-MM-dd"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        String otherStartMonth = (String) otherStartTimeMap.get(SalaryI18nUtil.getI18nLabel(91490, "其他福利起始缴纳月"));
        if (StringUtils.isNotBlank(otherStartMonth) && otherStartMonth.length() > 7) {
            otherStartMonth = otherStartMonth.substring(0, 7);
        }
        if (StringUtils.isNotBlank(otherStartMonth) && !SalaryDateUtil.checkYearMonth(otherStartMonth.replace("/",  "-"))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100320, "其他福利起始缴纳时间格式错误,正确格式为YYYY-MM或者yyyy-MM-dd"));
            excelComments.add(errorMessageMap);
            isError = true;
        }

        String otherEndMonth = (String) otherEndTimeMap.get(SalaryI18nUtil.getI18nLabel(91494, "其他福利最后缴纳月"));
        if (StringUtils.isNotBlank(otherEndMonth) && otherEndMonth.length() > 7) {
            otherEndMonth = otherEndMonth.substring(0, 7);
        }
        if (StringUtils.isNotBlank(otherEndMonth) && !SalaryDateUtil.checkYearMonth(otherEndMonth.replace("/",  "-"))) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100321, "其他福利最后缴纳时间格式错误,正确格式为YYYY-MM或者yyyy-MM-dd"));
            excelComments.add(errorMessageMap);
            isError = true;
        }
        if (StringUtils.isNotBlank((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"))) && schemeNameIdMap.get((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"))) == null) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "社保方案不存在"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else if (StringUtils.isNotBlank((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称")))
                && schemeNameIdMap.get((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"))) != null
                && !getInsuranceSchemeMapper().getById(schemeNameIdMap.get((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称")))).getWelfareType().equals(WelfareTypeEnum.SOCIAL_SECURITY.getValue())) {

            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "社保方案不属于社保福利类型"));
            excelComments.add(errorMessageMap);
            isError = true;

        } else if (StringUtils.isNotBlank((String) socialMap.get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称"))) && StringUtils.isBlank(socialStartMonth)) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "社保方案已设置，但未设置社保起始缴纳时间！"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else {
            insuranceArchivesSocialSchemePO = buildSocialPO(employeeId, welfareMap, singleAccount, schemeNameIdMap, paymentNameIdMap, creator);
        }
        if (StringUtils.isNotBlank((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"))) && schemeNameIdMap.get((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"))) == null) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100323, "公积金方案不存在"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else if (StringUtils.isNotBlank((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称")))
                && schemeNameIdMap.get((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"))) != null
                && !getInsuranceSchemeMapper().getById(schemeNameIdMap.get((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称")))).getWelfareType().equals(WelfareTypeEnum.ACCUMULATION_FUND.getValue())) {

            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "公积金方案不属于公积金福利类型"));
            excelComments.add(errorMessageMap);
            isError = true;

        } else if (StringUtils.isNotBlank((String) fundMap.get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称"))) && StringUtils.isBlank(fundStartMonth)) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "公积金方案已设置，但未设置公积金起始缴纳时间！"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else {
            insuranceArchivesFundSchemePO = buildFundPO(employeeId, welfareMap, singleAccount, schemeNameIdMap, paymentNameIdMap, creator);
        }
        if (StringUtils.isNotBlank((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称"))) && schemeNameIdMap.get((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称"))) == null) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100324, "其他福利方案不存在"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else if (StringUtils.isNotBlank((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称")))
                && schemeNameIdMap.get((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称"))) != null
                && !getInsuranceSchemeMapper().getById(schemeNameIdMap.get((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称")))).getWelfareType().equals(WelfareTypeEnum.OTHER.getValue())) {

            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "其他福利方案不属于其他福利类型"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else if (StringUtils.isNotBlank((String) otherMap.get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称"))) && StringUtils.isBlank(otherStartMonth)) {
            Map<String, String> errorMessageMap = Maps.newHashMap();
            errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100322, "其他福利方案已设置，但未设置其他福利起始缴纳时间！"));
            excelComments.add(errorMessageMap);
            isError = true;
        } else {
            insuranceArchivesOtherSchemePO = buildOtherPO(employeeId, welfareMap, singleAccount, schemeNameIdMap, paymentNameIdMap, creator);
        }
        /**************校验申报基数**************/
//        boolean welBaseDiffSign = siArchivesBiz.isDiffWelBase();
        boolean welBaseDiffSign = getSIArchivesService(user).isDiffWelBase();
        if (welBaseDiffSign) {
            for (Map.Entry<Long, String> entry : welfareMap.entrySet()) {
                String keyPerName = entry.getValue() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人");
                String keyComName = entry.getValue() + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位");
                String numberPerValue = findElement(singleAccount, keyPerName).get(keyPerName) == null ? "" : findElement(singleAccount, keyPerName).get(keyPerName).toString();
                String numberComValue = findElement(singleAccount, keyComName).get(keyComName) == null ? "" : findElement(singleAccount, keyComName).get(keyComName).toString();

                if (!"".equals(numberPerValue) && !NumberUtils.isParsable(numberPerValue)) {
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", rowIndex + keyPerName + SalaryI18nUtil.getI18nLabel(0, "请输入数字"));
                    excelComments.add(errorMessageMap);
                    isError = true;
                }
                if (!"".equals(numberComValue) && !NumberUtils.isParsable(numberComValue)) {
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", rowIndex + keyComName + SalaryI18nUtil.getI18nLabel(0, "请输入数字"));
                    excelComments.add(errorMessageMap);
                    isError = true;
                }
            }
        } else {
            for (Map.Entry<Long, String> entry : welfareMap.entrySet()) {
                String keyName = entry.getValue() + SalaryI18nUtil.getI18nLabel(0, "申报基数");
                String numberValue = findElement(singleAccount, keyName).get(keyName) == null ? "" : findElement(singleAccount, keyName).get(keyName).toString();
                if (!"".equals(numberValue) && !NumberUtils.isParsable(numberValue)) {
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", rowIndex + keyName + SalaryI18nUtil.getI18nLabel(0, "请输入数字"));
                    excelComments.add(errorMessageMap);
                    isError = true;
                }
            }
        }

        //生成福利档案基础信息数据
        InsuranceArchivesBaseInfoPO insuranceArchivesBaseInfoPO = buildBaseInfoPO(employeeId, singleAccount, paymentNameIdMap, creator, runStatus, employees.get(0).isExtEmp());

        //判断是否福利档案导入时，不符合上下限的基数调整为上限/下限
        SalarySysConfPO welBaseAutoAdjust = getSalarySysConfService(user).getOneByCode(WEL_BASE_AUTO_ADJUST);
        boolean welBaseAutoAdjustSign = welBaseAutoAdjust != null && welBaseAutoAdjust.getConfValue().equals(OpenEnum.OPEN.getValue());

        if (!isError && !welBaseAutoAdjustSign) {
            StringBuilder errorMsg = new StringBuilder("");
            insuranceArchivesAccountPO.setSocial(insuranceArchivesSocialSchemePO);
            insuranceArchivesAccountPO.setFund(insuranceArchivesFundSchemePO);
            insuranceArchivesAccountPO.setOther(insuranceArchivesOtherSchemePO);
            insuranceArchivesAccountPO.setBaseInfo(insuranceArchivesBaseInfoPO);
            //校验福利基数是否符合上下限要求，
            Boolean socialCheckBase = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesSocialSchemePO.getSocialSchemeId(), insuranceArchivesSocialSchemePO.getSocialPaymentBaseString(), PaymentScopeEnum.SCOPE_PERSON.getValue(), errorMsg);

            Boolean fundCheckBase = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesFundSchemePO.getFundSchemeId(), insuranceArchivesFundSchemePO.getFundPaymentBaseString(), PaymentScopeEnum.SCOPE_PERSON.getValue(), errorMsg);

            Boolean otherCheckBase = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesOtherSchemePO.getOtherSchemeId(), insuranceArchivesOtherSchemePO.getOtherPaymentBaseString(), PaymentScopeEnum.SCOPE_PERSON.getValue(), errorMsg);

            Boolean socialCheckBase2 = true;
            Boolean fundCheckBase2 = true;
            Boolean otherCheckBase2 = true;
            if (!welBaseDiffSign) {
                socialCheckBase2 = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesSocialSchemePO.getSocialSchemeId(), insuranceArchivesSocialSchemePO.getSocialPaymentBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue(), errorMsg);
                fundCheckBase2 = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesFundSchemePO.getFundSchemeId(), insuranceArchivesFundSchemePO.getFundPaymentBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue(), errorMsg);
                otherCheckBase2 = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesOtherSchemePO.getOtherSchemeId(), insuranceArchivesOtherSchemePO.getOtherPaymentBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue(), errorMsg);
            }
            Boolean socialCheckComBase = true;
            Boolean fundCheckComBase = true;
            Boolean otherCheckComBase = true;
            if (welBaseDiffSign) {
                socialCheckComBase = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesSocialSchemePO.getSocialSchemeId(), insuranceArchivesSocialSchemePO.getSocialPaymentComBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue(), errorMsg);
                fundCheckComBase = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesFundSchemePO.getFundSchemeId(), insuranceArchivesFundSchemePO.getFundPaymentComBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue(), errorMsg);
                otherCheckComBase = getSIArchivesService(user).checkWelBaseLimit(insuranceArchivesOtherSchemePO.getOtherSchemeId(), insuranceArchivesOtherSchemePO.getOtherPaymentComBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue(), errorMsg);
            }
            if (socialCheckBase && fundCheckBase && otherCheckBase && socialCheckBase2 && fundCheckBase2 && otherCheckBase2 && socialCheckComBase && fundCheckComBase && otherCheckComBase) {
                insuranceArchivesAccountPOS.add(insuranceArchivesAccountPO);
            } else {
                String checkMessage = "该条数据中";
                if (!socialCheckBase || !socialCheckBase2 || !socialCheckComBase) {
                    checkMessage = checkMessage + "社保福利基数、";
                }
                if (!fundCheckBase || !fundCheckBase2 || !fundCheckComBase) {
                    checkMessage = checkMessage + "公积金福利基数、";
                }
                if (!otherCheckBase || !otherCheckBase2 || !otherCheckComBase) {
                    checkMessage = checkMessage + "其他福利基数、";
                }
                checkMessage = checkMessage.substring(0, checkMessage.length() - 1);

                Map<String, String> errorMessageMap = Maps.newHashMap();
                errorMessageMap.put("message", rowIndex + SalaryI18nUtil.getI18nLabel(100312, checkMessage + "数值超出相关福利方案的基数上下限要求，不可导入！"));
                excelComments.add(errorMessageMap);
                isError = true;
            }

        } else if (!isError) {
            //校验福利基数是否符合上下限要求，不符合上下限的基数调整为上限 /下限
            String newSocialPaymentBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesSocialSchemePO.getSocialSchemeId(), insuranceArchivesSocialSchemePO.getSocialPaymentBaseString(), PaymentScopeEnum.SCOPE_PERSON.getValue());
            String newFundPaymentBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesFundSchemePO.getFundSchemeId(), insuranceArchivesFundSchemePO.getFundPaymentBaseString(), PaymentScopeEnum.SCOPE_PERSON.getValue());
            String newOtherPaymentBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesOtherSchemePO.getOtherSchemeId(), insuranceArchivesOtherSchemePO.getOtherPaymentBaseString(), PaymentScopeEnum.SCOPE_PERSON.getValue());

            insuranceArchivesSocialSchemePO.setSocialPaymentBaseString(newSocialPaymentBaseString);
            insuranceArchivesFundSchemePO.setFundPaymentBaseString(newFundPaymentBaseString);
            insuranceArchivesOtherSchemePO.setOtherPaymentBaseString(newOtherPaymentBaseString);
            if (!welBaseDiffSign) {
                newSocialPaymentBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesSocialSchemePO.getSocialSchemeId(), insuranceArchivesSocialSchemePO.getSocialPaymentBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue());
                newFundPaymentBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesFundSchemePO.getFundSchemeId(), insuranceArchivesFundSchemePO.getFundPaymentBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue());
                newOtherPaymentBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesOtherSchemePO.getOtherSchemeId(), insuranceArchivesOtherSchemePO.getOtherPaymentBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue());
                insuranceArchivesSocialSchemePO.setSocialPaymentBaseString(newSocialPaymentBaseString);
                insuranceArchivesFundSchemePO.setFundPaymentBaseString(newFundPaymentBaseString);
                insuranceArchivesOtherSchemePO.setOtherPaymentBaseString(newOtherPaymentBaseString);
            }

            if (welBaseDiffSign) {
                String newSocialPaymentComBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesSocialSchemePO.getSocialSchemeId(), insuranceArchivesSocialSchemePO.getSocialPaymentComBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue());
                String newFundPaymentComBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesFundSchemePO.getFundSchemeId(), insuranceArchivesFundSchemePO.getFundPaymentComBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue());
                String newOtherPaymentComBaseString = getSIArchivesService(user).checkAndBuildWelBaseWithLimit(insuranceArchivesOtherSchemePO.getOtherSchemeId(), insuranceArchivesOtherSchemePO.getOtherPaymentComBaseString(), PaymentScopeEnum.SCOPE_COMPANY.getValue());

                insuranceArchivesSocialSchemePO.setSocialPaymentComBaseString(newSocialPaymentComBaseString);
                insuranceArchivesFundSchemePO.setFundPaymentComBaseString(newFundPaymentComBaseString);
                insuranceArchivesOtherSchemePO.setOtherPaymentComBaseString(newOtherPaymentComBaseString);
            }

            insuranceArchivesAccountPO.setSocial(insuranceArchivesSocialSchemePO);
            insuranceArchivesAccountPO.setFund(insuranceArchivesFundSchemePO);
            insuranceArchivesAccountPO.setOther(insuranceArchivesOtherSchemePO);
            insuranceArchivesAccountPO.setBaseInfo(insuranceArchivesBaseInfoPO);

            insuranceArchivesAccountPOS.add(insuranceArchivesAccountPO);
        }
        return isError;
    }


    public Map<String, Object> findElement(List<Map<String, Object>> singleAccount, String target) {
        for (Map<String, Object> e : singleAccount) {
            if (e.containsKey(target)) {
                return e;
            }
        }
        return new HashMap<>();
    }


    public InsuranceArchivesSocialSchemePO buildSocialPO(Long employeeId, Map<Long, String> welfareMap, List<Map<String, Object>> singleAccount, Map<String, Long> schemeNameIdMap, Map<String, Long> paymentNameIdMap, Long creator) {

        if (employeeId == null) {
            return null;
        }
        Long paymentOrg = paymentNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91325, "个税扣缴义务人")).get(SalaryI18nUtil.getI18nLabel(91325, "个税扣缴义务人")));
        List<InsuranceArchivesSocialSchemePO> oldSocialSchemeInfos = getSocialSchemeMapper().getSocialByEmployeeIdAndPayOrg(InsuranceArchivesEmployeePO
                .builder()
                .employeeId(employeeId)
                .paymentOrganization(paymentOrg)
                .build());
        InsuranceArchivesSocialSchemePO oldSocialSchemePO = new InsuranceArchivesSocialSchemePO();
        InsuranceArchivesSocialSchemePO insuranceArchivesSocialSchemePO = new InsuranceArchivesSocialSchemePO();

        //设置社保账号、起始缴纳月、最后缴纳月
        String socialAccount = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91324, "社保账号")).get(SalaryI18nUtil.getI18nLabel(91324, "社保账号"));
        Long socialSchemeId = schemeNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91323, "社保方案名称")).get(SalaryI18nUtil.getI18nLabel(91323, "社保方案名称")));
        HashMap<String, String> oldSocialBaseMap = new HashMap<>();
        HashMap<String, String> oldSocialComBaseMap = new HashMap<>();
        if (oldSocialSchemeInfos.size() > 0) {
            oldSocialSchemePO = oldSocialSchemeInfos.get(0);
            encryptUtil.decrypt(oldSocialSchemePO, InsuranceArchivesSocialSchemePO.class);
            BeanUtils.copyProperties(oldSocialSchemePO, insuranceArchivesSocialSchemePO);
            //社保基数
            oldSocialBaseMap = JSON.parseObject(oldSocialSchemePO.getSocialPaymentBaseString(), new HashMap<String, String>().getClass());
            oldSocialComBaseMap = JSON.parseObject(oldSocialSchemePO.getSocialPaymentComBaseString(), new HashMap<String, String>().getClass());
        }

        insuranceArchivesSocialSchemePO.setId(IdGenerator.generate());
        if (StringUtils.isNotBlank(socialAccount)) {
            insuranceArchivesSocialSchemePO.setSocialAccount(socialAccount);
        }
        if (socialSchemeId != null) {
            insuranceArchivesSocialSchemePO.setSocialSchemeId(socialSchemeId);
        }
        String socialStartDate = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91319, "社保起始缴纳月")).get(SalaryI18nUtil.getI18nLabel(91319, "社保起始缴纳月"));
        if (StringUtils.isNotBlank(socialStartDate) && socialStartDate.length() >= 7) {
            socialStartDate = socialStartDate.substring(0, 7).replace("/",  "-");
            insuranceArchivesSocialSchemePO.setSocialStartTime(socialStartDate);
        }

        String socialEndDate = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91320, "社保最后缴纳月")).get(SalaryI18nUtil.getI18nLabel(91320, "社保最后缴纳月"));
        if (StringUtils.isNotBlank(socialEndDate) && socialEndDate.length() >= 7) {
            socialEndDate = socialEndDate.substring(0, 7).replace("/",  "-");
            insuranceArchivesSocialSchemePO.setSocialEndTime(socialEndDate);
        }

        insuranceArchivesSocialSchemePO.setTenantKey("");
        insuranceArchivesSocialSchemePO.setWelfareType(WelfareTypeEnum.SOCIAL_SECURITY.getValue());
        insuranceArchivesSocialSchemePO.setUpdateTime(new Date());
        insuranceArchivesSocialSchemePO.setPaymentOrganization(paymentOrg);
        insuranceArchivesSocialSchemePO.setNonPayment(NonPaymentEnum.YES.getValue());
        insuranceArchivesSocialSchemePO.setCreator(creator);
        insuranceArchivesSocialSchemePO.setCreateTime(new Date());
        insuranceArchivesSocialSchemePO.setUpdateTime(new Date());
        insuranceArchivesSocialSchemePO.setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue());
        insuranceArchivesSocialSchemePO.setEmployeeId(employeeId);
        insuranceArchivesSocialSchemePO.setUnderTake(UndertakerEnum.SCOPE_PERSON.getValue());
        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = getInsuranceSchemeDetailMapper().queryListBySchemeId(insuranceArchivesSocialSchemePO.getSocialSchemeId());
        encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);

//        boolean welBaseDiffSign = siArchivesBiz.isDiffWelBase();
        boolean welBaseDiffSign = getSIArchivesService(user).isDiffWelBase();
        if (CollectionUtils.isNotEmpty(insuranceSchemeDetailPOS)) {
            List<Long> insuranceIds = insuranceSchemeDetailPOS.stream().map(InsuranceSchemeDetailPO::getInsuranceId).collect(Collectors.toList());
            HashMap<String, String> socialPaymentBase = new HashMap<>();
            HashMap<String, String> socialPaymentComBase = new HashMap<>();
            for (Long insuranceId : insuranceIds) {
                if (StringUtils.isBlank(welfareMap.get(insuranceId))) {
                    continue;
                }
                if (welBaseDiffSign) {
                    Map<String, Object> itemPerMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人"));
                    if (itemPerMap != null) {
                        String itemValue = (String) itemPerMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            socialPaymentBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldSocialBaseMap != null && StringUtils.isNotBlank(oldSocialBaseMap.get(String.valueOf(insuranceId)))) {
                            socialPaymentBase.put(String.valueOf(insuranceId), oldSocialBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                    Map<String, Object> itemComMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位"));
                    if (itemComMap != null) {
                        String itemValue = (String) itemComMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            socialPaymentComBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldSocialComBaseMap != null && StringUtils.isNotBlank(oldSocialComBaseMap.get(String.valueOf(insuranceId)))) {
                            socialPaymentComBase.put(String.valueOf(insuranceId), oldSocialComBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                    insuranceArchivesSocialSchemePO.setSocialPaymentComBaseString(JSON.toJSONString(socialPaymentComBase));
                } else {
                    Map<String, Object> itemMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                    if (itemMap != null) {
                        String itemValue = (String) itemMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            socialPaymentBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldSocialBaseMap != null && StringUtils.isNotBlank(oldSocialBaseMap.get(String.valueOf(insuranceId)))) {
                            socialPaymentBase.put(String.valueOf(insuranceId), oldSocialBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                }

            }
            insuranceArchivesSocialSchemePO.setSocialPaymentBaseString(JSON.toJSONString(socialPaymentBase));
        }
        return insuranceArchivesSocialSchemePO;
    }


    public InsuranceArchivesFundSchemePO buildFundPO(Long employeeId, Map<Long, String> welfareMap, List<Map<String, Object>> singleAccount, Map<String, Long> schemeNameIdMap, Map<String, Long> paymentNameIdMap, Long creator) {

        if (employeeId == null) {
            return null;
        }
        Long paymentOrg = paymentNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91325, "个税扣缴义务人")).get(SalaryI18nUtil.getI18nLabel(91325, "个税扣缴义务人")));
        List<InsuranceArchivesFundSchemePO> oldFundSchemeInfos = getFundSchemeMapper().getFundByEmployeeIdAndPayOrg(InsuranceArchivesEmployeePO
                .builder()
                .employeeId(employeeId)
                .paymentOrganization(paymentOrg)
                .build());
        InsuranceArchivesFundSchemePO oldFundSchemePO = new InsuranceArchivesFundSchemePO();
        InsuranceArchivesFundSchemePO insuranceArchivesFundSchemePO = new InsuranceArchivesFundSchemePO();

        //设置公积金账号、起始缴纳月、最后缴纳月
        String fundAccount = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91486, "公积金账号")).get(SalaryI18nUtil.getI18nLabel(91486, "公积金账号"));
        String supplementFundAccount = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91487, "补充公积金账号")).get(SalaryI18nUtil.getI18nLabel(91487, "补充公积金账号"));
        Long fundSchemeId = schemeNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称")).get(SalaryI18nUtil.getI18nLabel(91485, "公积金方案名称")));
        HashMap<String, String> oldFundBaseMap = new HashMap<>();
        HashMap<String, String> oldFundComBaseMap = new HashMap<>();
        if (oldFundSchemeInfos.size() > 0) {
            oldFundSchemePO = oldFundSchemeInfos.get(0);
            encryptUtil.decrypt(oldFundSchemePO, InsuranceArchivesFundSchemePO.class);
            BeanUtils.copyProperties(oldFundSchemePO, insuranceArchivesFundSchemePO);
            //社保基数
            oldFundBaseMap = JSON.parseObject(oldFundSchemePO.getFundPaymentBaseString(), new HashMap<String, String>().getClass());
            oldFundComBaseMap = JSON.parseObject(oldFundSchemePO.getFundPaymentComBaseString(), new HashMap<String, String>().getClass());
        }

        insuranceArchivesFundSchemePO.setId(IdGenerator.generate());
        insuranceArchivesFundSchemePO.setCreator(creator);
        insuranceArchivesFundSchemePO.setTenantKey("");
        insuranceArchivesFundSchemePO.setCreateTime(new Date());
        insuranceArchivesFundSchemePO.setUpdateTime(new Date());
        if (fundSchemeId != null) {
            insuranceArchivesFundSchemePO.setFundSchemeId(fundSchemeId);
        }
        if (StringUtils.isNotBlank(fundAccount)) {
            insuranceArchivesFundSchemePO.setFundAccount(fundAccount);
        }
        if (StringUtils.isNotBlank(supplementFundAccount)) {
            insuranceArchivesFundSchemePO.setSupplementFundAccount(supplementFundAccount);
        }
        String fundStartDate = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91483, "公积金起始缴纳月")).get(SalaryI18nUtil.getI18nLabel(91483, "公积金起始缴纳月"));
        if (StringUtils.isNotBlank(fundStartDate) && fundStartDate.length() >= 7) {
            fundStartDate = fundStartDate.substring(0, 7).replace("/",  "-");
            insuranceArchivesFundSchemePO.setFundStartTime(fundStartDate);
        }

        String fundEndDate = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91484, "公积金最后缴纳月")).get(SalaryI18nUtil.getI18nLabel(91484, "公积金最后缴纳月"));
        if (StringUtils.isNotBlank(fundEndDate) && fundEndDate.length() >= 7) {
            fundEndDate = fundEndDate.substring(0, 7).replace("/",  "-");
            insuranceArchivesFundSchemePO.setFundEndTime(fundEndDate);
        }

        insuranceArchivesFundSchemePO.setWelfareType(WelfareTypeEnum.ACCUMULATION_FUND.getValue());
        insuranceArchivesFundSchemePO.setPaymentOrganization(paymentOrg);
        insuranceArchivesFundSchemePO.setNonPayment(NonPaymentEnum.YES.getValue());
        insuranceArchivesFundSchemePO.setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue());
        insuranceArchivesFundSchemePO.setUnderTake(UndertakerEnum.SCOPE_PERSON.getValue());
        insuranceArchivesFundSchemePO.setEmployeeId(employeeId);

        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = getInsuranceSchemeDetailMapper().queryListBySchemeId(insuranceArchivesFundSchemePO.getFundSchemeId());
        encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
//        boolean welBaseDiffSign = siArchivesBiz.isDiffWelBase();
        boolean welBaseDiffSign = getSIArchivesService(user).isDiffWelBase();
        if (CollectionUtils.isNotEmpty(insuranceSchemeDetailPOS)) {
            List<Long> insuranceIds = insuranceSchemeDetailPOS.stream().map(InsuranceSchemeDetailPO::getInsuranceId).collect(Collectors.toList());
            HashMap<String, String> fundPaymentBase = new HashMap<>();
            HashMap<String, String> fundPaymentComBase = new HashMap<>();
            for (Long insuranceId : insuranceIds) {
                if (StringUtils.isBlank(welfareMap.get(insuranceId))) {
                    continue;
                }
                if (welBaseDiffSign) {
                    Map<String, Object> itemPerMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人"));
                    if (itemPerMap != null) {
                        String itemValue = (String) itemPerMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            fundPaymentBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldFundBaseMap != null && StringUtils.isNotBlank(oldFundBaseMap.get(String.valueOf(insuranceId)))) {
                            fundPaymentBase.put(String.valueOf(insuranceId), oldFundBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                    Map<String, Object> itemComMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位"));
                    if (itemComMap != null) {
                        String itemValue = (String) itemComMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            fundPaymentComBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldFundComBaseMap != null && StringUtils.isNotBlank(oldFundComBaseMap.get(String.valueOf(insuranceId)))) {
                            fundPaymentComBase.put(String.valueOf(insuranceId), oldFundComBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                    insuranceArchivesFundSchemePO.setFundPaymentComBaseString(JSON.toJSONString(fundPaymentComBase));
                } else {
                    Map<String, Object> itemMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                    if (itemMap != null) {
                        String itemValue = (String) itemMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            fundPaymentBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldFundBaseMap != null && StringUtils.isNotBlank(oldFundBaseMap.get(String.valueOf(insuranceId)))) {
                            fundPaymentBase.put(String.valueOf(insuranceId), oldFundBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                }

            }
            insuranceArchivesFundSchemePO.setFundPaymentBaseString(JSON.toJSONString(fundPaymentBase));
        }
        return insuranceArchivesFundSchemePO;
    }


    public InsuranceArchivesOtherSchemePO buildOtherPO(Long employeeId, Map<Long, String> welfareMap, List<Map<String, Object>> singleAccount, Map<String, Long> schemeNameIdMap, Map<String, Long> paymentNameIdMap, Long creator) {

        if (employeeId == null) {
            return null;
        }Long paymentOrg = paymentNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91325, "个税扣缴义务人")).get(SalaryI18nUtil.getI18nLabel(91325, "个税扣缴义务人")));
        List<InsuranceArchivesOtherSchemePO> oldOtherSchemeInfos = getOtherSchemeMapper().getOtherByEmployeeIdAndPayOrg(InsuranceArchivesEmployeePO
                .builder()
                .employeeId(employeeId)
                .paymentOrganization(paymentOrg)
                .build());
        InsuranceArchivesOtherSchemePO oldOtherSchemePO = new InsuranceArchivesOtherSchemePO();
        InsuranceArchivesOtherSchemePO insuranceArchivesOtherSchemePO = new InsuranceArchivesOtherSchemePO();

        //设置其他福利方案、起始缴纳月、最后缴纳月
        Long otherSchemeId = schemeNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称")).get(SalaryI18nUtil.getI18nLabel(91496, "其他福利方案名称")));
        HashMap<String, String> oldOtherBaseMap = new HashMap<>();
        HashMap<String, String> oldOtherComBaseMap = new HashMap<>();
        if (oldOtherSchemeInfos.size() > 0) {
            oldOtherSchemePO = oldOtherSchemeInfos.get(0);
            encryptUtil.decrypt(oldOtherSchemePO, InsuranceArchivesOtherSchemePO.class);
            BeanUtils.copyProperties(oldOtherSchemePO, insuranceArchivesOtherSchemePO);
            //社保基数
            oldOtherBaseMap = JSON.parseObject(oldOtherSchemePO.getOtherPaymentBaseString(), new HashMap<String, String>().getClass());
            oldOtherComBaseMap = JSON.parseObject(oldOtherSchemePO.getOtherPaymentComBaseString(), new HashMap<String, String>().getClass());
        }

        insuranceArchivesOtherSchemePO.setId(IdGenerator.generate());
        insuranceArchivesOtherSchemePO.setCreator(creator);
        insuranceArchivesOtherSchemePO.setTenantKey("");
        insuranceArchivesOtherSchemePO.setCreateTime(new Date());
        insuranceArchivesOtherSchemePO.setUpdateTime(new Date());
        if (otherSchemeId != null) {
            insuranceArchivesOtherSchemePO.setOtherSchemeId(otherSchemeId);
        }
        String otherStartDate = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91490, "其他福利起始缴纳月")).get(SalaryI18nUtil.getI18nLabel(91490, "其他福利起始缴纳月"));
        if (StringUtils.isNotBlank(otherStartDate) && otherStartDate.length() >= 7) {
            otherStartDate = otherStartDate.substring(0, 7).replace("/",  "-");
            insuranceArchivesOtherSchemePO.setOtherStartTime(otherStartDate);
        }

        String otherEndDate = (String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91494, "其他福利最后缴纳月")).get(SalaryI18nUtil.getI18nLabel(91494, "其他福利最后缴纳月"));
        if (StringUtils.isNotBlank(otherEndDate) && otherEndDate.length() >= 7) {
            otherEndDate = otherEndDate.substring(0, 7).replace("/",  "-");
            insuranceArchivesOtherSchemePO.setOtherEndTime(otherEndDate);
        }

        insuranceArchivesOtherSchemePO.setPaymentOrganization(paymentOrg);
        insuranceArchivesOtherSchemePO.setWelfareType(WelfareTypeEnum.OTHER.getValue());
        insuranceArchivesOtherSchemePO.setNonPayment(NonPaymentEnum.YES.getValue());
        insuranceArchivesOtherSchemePO.setDeleteType(DeleteTypeEnum.NOT_DELETED.getValue());
        insuranceArchivesOtherSchemePO.setUnderTake(UndertakerEnum.SCOPE_PERSON.getValue());
        insuranceArchivesOtherSchemePO.setEmployeeId(employeeId);
        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = getInsuranceSchemeDetailMapper().queryListBySchemeId(insuranceArchivesOtherSchemePO.getOtherSchemeId());
        encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
//        boolean welBaseDiffSign = siArchivesBiz.isDiffWelBase();
        boolean welBaseDiffSign = getSIArchivesService(user).isDiffWelBase();
        if (CollectionUtils.isNotEmpty(insuranceSchemeDetailPOS)) {
            List<Long> insuranceIds = insuranceSchemeDetailPOS.stream().map(InsuranceSchemeDetailPO::getInsuranceId).collect(Collectors.toList());
            HashMap<String, String> otherPaymentBase = new HashMap<>();
            HashMap<String, String> otherPaymentComBase = new HashMap<>();
            for (Long insuranceId : insuranceIds) {
                if (StringUtils.isBlank(welfareMap.get(insuranceId))) {
                    continue;
                }
                if (welBaseDiffSign) {
                    Map<String, Object> itemPerMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人"));
                    if (itemPerMap != null) {
                        String itemValue = (String) itemPerMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "个人"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            otherPaymentBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldOtherBaseMap != null && StringUtils.isNotBlank(oldOtherBaseMap.get(String.valueOf(insuranceId)))) {
                            otherPaymentBase.put(String.valueOf(insuranceId), oldOtherBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                    Map<String, Object> itemComMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位"));
                    if (itemComMap != null) {
                        String itemValue = (String) itemComMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数") + SalaryI18nUtil.getI18nLabel(0, "单位"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            otherPaymentComBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldOtherComBaseMap != null && StringUtils.isNotBlank(oldOtherComBaseMap.get(String.valueOf(insuranceId)))) {
                            otherPaymentComBase.put(String.valueOf(insuranceId), oldOtherComBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                    insuranceArchivesOtherSchemePO.setOtherPaymentComBaseString(JSON.toJSONString(otherPaymentComBase));
                } else {
                    Map<String, Object> itemMap = findElement(singleAccount, welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                    if (itemMap != null) {
                        String itemValue = (String) itemMap.get(welfareMap.get(insuranceId) + SalaryI18nUtil.getI18nLabel(0, "申报基数"));
                        if (StringUtils.isNotBlank(itemValue)) {
                            otherPaymentBase.put(String.valueOf(insuranceId), itemValue);
                        } else if (oldOtherBaseMap != null && StringUtils.isNotBlank(oldOtherBaseMap.get(String.valueOf(insuranceId)))) {
                            otherPaymentBase.put(String.valueOf(insuranceId), oldOtherBaseMap.get(String.valueOf(insuranceId)));
                        }
                    }
                }

            }
            insuranceArchivesOtherSchemePO.setOtherPaymentBaseString(JSON.toJSONString(otherPaymentBase));
        }
        return insuranceArchivesOtherSchemePO;
    }

    public InsuranceArchivesBaseInfoPO buildBaseInfoPO(Long employeeId, List<Map<String, Object>> singleAccount, Map<String, Long> paymentNameIdMap, Long creator, String runStatus, Boolean isExtEmp) {
        if (employeeId == null) {
            return null;
        }
        InsuranceArchivesBaseInfoPO insuranceArchivesBaseInfoPO = new InsuranceArchivesBaseInfoPO();
        insuranceArchivesBaseInfoPO.setEmployeeId(employeeId);
        insuranceArchivesBaseInfoPO.setId(IdGenerator.generate());
        insuranceArchivesBaseInfoPO.setCreateTime(new Date());
        insuranceArchivesBaseInfoPO.setDeleteType(0);
        insuranceArchivesBaseInfoPO.setCreator(creator);
        insuranceArchivesBaseInfoPO.setRunStatus(runStatus);
        insuranceArchivesBaseInfoPO.setUpdateTime(new Date());
        insuranceArchivesBaseInfoPO.setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY);
        insuranceArchivesBaseInfoPO.setPaymentOrganization(paymentNameIdMap.get((String) findElement(singleAccount, SalaryI18nUtil.getI18nLabel(91497, "个税扣缴义务人")).get(SalaryI18nUtil.getI18nLabel(91497, "个税扣缴义务人"))));
        if (isExtEmp) {
            insuranceArchivesBaseInfoPO.setEmployeeType(1);
        }

        return insuranceArchivesBaseInfoPO;
    }

    public void handleImportData(List<InsuranceArchivesAccountPO> insuranceArchivesAccountPOS, SIArchiveImportParam param) {
        List<InsuranceArchivesBaseInfoPO> baseInfoPOS = insuranceArchivesAccountPOS.stream().filter(Objects::nonNull).map(InsuranceArchivesAccountPO::getBaseInfo).collect(Collectors.toList());
        //去除员工id+个税扣缴义务人下重复的数据
        baseInfoPOS = baseInfoPOS.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getPaymentOrganization() + "-" + f.getEmployeeId()))), ArrayList::new));
        //老数据map
        Map<String, InsuranceArchivesSocialSchemePO> oldSocialArchiveMap = getSocialArchiveMap(baseInfoPOS);
        Map<String, InsuranceArchivesFundSchemePO> oldFundArchiveMap = getFundArchiveMap(baseInfoPOS);
        Map<String, InsuranceArchivesOtherSchemePO> oldOtherArchiveMap = getOtherArchiveMap(baseInfoPOS);
        //导入社保档案
        List<InsuranceArchivesSocialSchemePO> socialSchemePOS = insuranceArchivesAccountPOS.stream().filter(Objects::nonNull).map(InsuranceArchivesAccountPO::getSocial).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(socialSchemePOS)) {
            //去除员工id+个税扣缴义务人下重复的数据
            socialSchemePOS = socialSchemePOS.stream()
                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getPaymentOrganization() + "-" + f.getEmployeeId()))), ArrayList::new));

            //生成福利档案基数调整历史记录
//            List<InsuranceArchivesBaseHistoryPO> adjustSocialHistoryPOList = siArchivesBiz.dealSocialBaseAdjustInfoList(socialSchemePOS, (long) user.getUID());
            List<InsuranceArchivesBaseHistoryPO> adjustSocialHistoryPOList = getSIArchivesService(user).dealSocialBaseAdjustInfoList(socialSchemePOS, (long) user.getUID());

            //根据人员id和个税扣缴义务人id删除对应旧档案
            socialSchemePOS.forEach(getSocialSchemeMapper()::deleteByEmployeeIdAndPayOrg);

            //新建新档案
            List<InsuranceArchivesSocialSchemePO> insuranceArchivesSocialSchemePOS = encryptUtil.encryptList(socialSchemePOS, InsuranceArchivesSocialSchemePO.class);
            List<List<InsuranceArchivesSocialSchemePO>> partition = Lists.partition(insuranceArchivesSocialSchemePOS, 100);
            partition.forEach(getSocialSchemeMapper()::batchSave);

            //新建福利档案基数调整历史记录
//            siArchivesBiz.batchInsertAdjustHistory(adjustSocialHistoryPOList, user.getUID());
            getSIArchivesService(user).batchInsertAdjustHistory(adjustSocialHistoryPOList);
        }
        //导入公积金档案
        List<InsuranceArchivesFundSchemePO> fundSchemePOS = insuranceArchivesAccountPOS.stream().filter(Objects::nonNull).map(InsuranceArchivesAccountPO::getFund).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(fundSchemePOS)) {
            //去除员工id+个税扣缴义务人下重复的数据
            fundSchemePOS = fundSchemePOS.stream()
                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getPaymentOrganization() + "-" + f.getEmployeeId()))), ArrayList::new));

            //生成福利档案基数调整历史记录
//            List<InsuranceArchivesBaseHistoryPO> adjustFundHistoryPOList = siArchivesBiz.dealFundBaseAdjustInfoList(fundSchemePOS, (long) user.getUID());
            List<InsuranceArchivesBaseHistoryPO> adjustFundHistoryPOList = getSIArchivesService(user).dealFundBaseAdjustInfoList(fundSchemePOS, (long) user.getUID());
            //根据人员id和个税扣缴义务人id删除对应档案
            fundSchemePOS.forEach(getFundSchemeMapper()::deleteByEmployeeIdAndPayOrg);
            //新建新档案
            List<InsuranceArchivesFundSchemePO> insuranceArchivesFundSchemePOS = encryptUtil.encryptList(fundSchemePOS, InsuranceArchivesFundSchemePO.class);
            List<List<InsuranceArchivesFundSchemePO>> partition = Lists.partition(insuranceArchivesFundSchemePOS, 100);
            partition.forEach(getFundSchemeMapper()::batchSave);
            //新建福利档案基数调整历史记录
//            siArchivesBiz.batchInsertAdjustHistory(adjustFundHistoryPOList, user.getUID());
            getSIArchivesService(user).batchInsertAdjustHistory(adjustFundHistoryPOList);
        }
        //导入其他福利档案
        List<InsuranceArchivesOtherSchemePO> otherSchemePOS = insuranceArchivesAccountPOS.stream().filter(Objects::nonNull).map(InsuranceArchivesAccountPO::getOther).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(otherSchemePOS)) {
            //去除员工id+个税扣缴义务人下重复的数据
            otherSchemePOS = otherSchemePOS.stream()
                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getPaymentOrganization() + "-" + f.getEmployeeId()))), ArrayList::new));

            //生成福利档案基数调整历史记录
//            List<InsuranceArchivesBaseHistoryPO> adjustOtherHistoryPOList = siArchivesBiz.dealOtherBaseAdjustInfoList(otherSchemePOS, (long) user.getUID());
            List<InsuranceArchivesBaseHistoryPO> adjustOtherHistoryPOList = getSIArchivesService(user).dealOtherBaseAdjustInfoList(otherSchemePOS, (long) user.getUID());

            //根据人员id和个税扣缴义务人id删除对应档案
            otherSchemePOS.forEach(getOtherSchemeMapper()::deleteByEmployeeIdAndPayOrg);
            //新建新档案
            List<InsuranceArchivesOtherSchemePO> insuranceArchivesOtherSchemePOS = encryptUtil.encryptList(otherSchemePOS, InsuranceArchivesOtherSchemePO.class);
            List<List<InsuranceArchivesOtherSchemePO>> partition = Lists.partition(insuranceArchivesOtherSchemePOS, 100);
            partition.forEach(getOtherSchemeMapper()::batchSave);
            //新建福利档案基数调整历史记录
//            siArchivesBiz.batchInsertAdjustHistory(adjustOtherHistoryPOList, user.getUID());
            getSIArchivesService(user).batchInsertAdjustHistory(adjustOtherHistoryPOList);
        }
        //导入福利档案基础信息
//        List<InsuranceArchivesBaseInfoPO> baseInfoPOS = insuranceArchivesAccountPOS.stream().filter(Objects::nonNull).map(InsuranceArchivesAccountPO::getBaseInfo).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(baseInfoPOS)) {
//            baseInfoPOS = baseInfoPOS.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(InsuranceArchivesBaseInfoPO::getEmployeeId))), ArrayList::new));
//            //去除员工id+个税扣缴义务人下重复的数据
//            baseInfoPOS = baseInfoPOS.stream()
//                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getPaymentOrganization() + "-" + f.getEmployeeId()))), ArrayList::new));
            //根据人员id和个税扣缴义务人id删除对应档案
            baseInfoPOS.forEach(getInsuranceBaseInfoMapper()::deleteByEmployeeIdAndPayOrg);
            //分批批量删除
            List<Long> baseInfoEmployeeIds = baseInfoPOS.stream().map(InsuranceArchivesBaseInfoPO::getEmployeeId).collect(Collectors.toList());
//            List<List<Long>> employeeIdPartition = Lists.partition(baseInfoEmployeeIds, 100);
//            employeeIdPartition.forEach(getInsuranceBaseInfoMapper()::batchDeleteByEmployeeIds);
            //查询目标人员的剩余的福利档案基础信息（社保、公积金、其他福利档案id）
//            List<InsuranceArchivesBaseInfoPO> moreBaseInfoPOS = getInsuranceBaseInfoMapper().getInsuranceBaseInfoListByInsuranceDetail(baseInfoEmployeeIds);
            List<InsuranceArchivesBaseInfoPO> moreBaseInfoPOS = new ArrayList<>();
            List<List<Long>> partitionInfo = Lists.partition((List<Long>) baseInfoEmployeeIds, 1000);
            partitionInfo.forEach(part -> moreBaseInfoPOS.addAll(
                    getInsuranceBaseInfoMapper().getInsuranceBaseInfoListByInsuranceDetail(part)));
            List<InsuranceArchivesBaseInfoPO> newInsuranceArchivesBaseInfoList = new ArrayList<>();
            //设置社保、公积金、其他福利档案id
            for (InsuranceArchivesBaseInfoPO po : baseInfoPOS) {
                InsuranceArchivesBaseInfoPO moreBaseInfo = moreBaseInfoPOS.stream().filter(s -> Objects.equals(s.getEmployeeId(), po.getEmployeeId()) && Objects.equals(s.getPaymentOrganization(), po.getPaymentOrganization())).findFirst().orElse(null);
                po.setSocialArchivesId(moreBaseInfo.getSocialArchivesId());
                po.setFundArchivesId(moreBaseInfo.getFundArchivesId());
                po.setOtherArchivesId(moreBaseInfo.getOtherArchivesId());
                newInsuranceArchivesBaseInfoList.add(po);
            }
            //分批批量入库
            List<List<InsuranceArchivesBaseInfoPO>> partition = Lists.partition(newInsuranceArchivesBaseInfoList, 100);
            partition.forEach(getInsuranceBaseInfoMapper()::batchSave);
            //记录操作日志
            //获取新数据map和老数据map
            Map<String, InsuranceArchivesSocialSchemePO> newSocialArchiveMap = getSocialArchiveMap(baseInfoPOS);
            Map<String, InsuranceArchivesFundSchemePO> newFundArchiveMap = getFundArchiveMap(baseInfoPOS);
            Map<String, InsuranceArchivesOtherSchemePO> newOtherArchiveMap = getOtherArchiveMap(baseInfoPOS);
            newInsuranceArchivesBaseInfoList.forEach(targetPO -> {
                InsuranceArchivesSocialSchemePO targetSocialDetail = newSocialArchiveMap.get(targetPO.getPaymentOrganization() + "-" + targetPO.getEmployeeId());
                InsuranceArchivesFundSchemePO targetFundDetail = newFundArchiveMap.get(targetPO.getPaymentOrganization() + "-" + targetPO.getEmployeeId());
                InsuranceArchivesOtherSchemePO targetOtherDetail = newOtherArchiveMap.get(targetPO.getPaymentOrganization() + "-" + targetPO.getEmployeeId());
                DataCollectionEmployee empInfo = getSalaryEmployeeService(user).getEmployeeById(targetPO.getEmployeeId());
                TaxAgentPO taxAgentInfo = getTaxAgentMapper().getById(targetPO.getPaymentOrganization());
                if (targetSocialDetail != null) {
                    LoggerContext<InsuranceArchivesSocialSchemePO> loggerContext = new LoggerContext<>();
                    loggerContext.setUser(user);
                    loggerContext.setTargetId(String.valueOf(targetPO.getId()));
                    loggerContext.setTargetName(taxAgentInfo.getName() + "-" + empInfo.getUsername());
                    loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
                    loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "福利档案-社保明细导入"));
                    loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利档案-社保明细导入") + ": " + taxAgentInfo.getName() + "-" + empInfo.getUsername());
                    loggerContext.setOldValues(oldSocialArchiveMap.get(targetPO.getPaymentOrganization() + "-" + targetPO.getEmployeeId()));
                    loggerContext.setNewValues(targetSocialDetail);
                    SalaryElogConfig.siArchivesLoggerTemplate.write(loggerContext);
                }
                if (targetFundDetail != null) {
                    LoggerContext<InsuranceArchivesFundSchemePO> loggerContext = new LoggerContext<>();
                    loggerContext.setUser(user);
                    loggerContext.setTargetId(String.valueOf(targetPO.getId()));
                    loggerContext.setTargetName(taxAgentInfo.getName() + "-" + empInfo.getUsername());
                    loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
                    loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "福利档案-公积金明细导入"));
                    loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利档案-公积金明细导入") + ": " + taxAgentInfo.getName() + "-" + empInfo.getUsername());
                    loggerContext.setOldValues(oldFundArchiveMap.get(targetPO.getPaymentOrganization() + "-" + targetPO.getEmployeeId()));
                    loggerContext.setNewValues(targetFundDetail);
                    SalaryElogConfig.siArchivesLoggerTemplate.write(loggerContext);
                }
                if (targetOtherDetail != null) {
                    LoggerContext<InsuranceArchivesOtherSchemePO> loggerContext = new LoggerContext<>();
                    loggerContext.setUser(user);
                    loggerContext.setTargetId(String.valueOf(targetPO.getId()));
                    loggerContext.setTargetName(taxAgentInfo.getName() + "-" + empInfo.getUsername());
                    loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
                    loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "福利档案-其他福利明细导入"));
                    loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利档案-其他福利明细导入") + ": " + taxAgentInfo.getName() + "-" + empInfo.getUsername());
                    loggerContext.setOldValues(oldOtherArchiveMap.get(targetPO.getPaymentOrganization() + "-" + targetPO.getEmployeeId()));
                    loggerContext.setNewValues(targetOtherDetail);
                    SalaryElogConfig.siArchivesLoggerTemplate.write(loggerContext);
                }
            });
        }
        //新增人员范围（会自动生成人员档案）
        if (CollectionUtils.isNotEmpty(param.getTaxAgentRanges())) {
            param.getTaxAgentRanges().forEach(getTaxAgentManageRangeService(user)::save);
        }
    }

    private Map<String, InsuranceArchivesSocialSchemePO> getSocialArchiveMap(List<InsuranceArchivesBaseInfoPO> baseInfoPOS) {
        Map<String, InsuranceArchivesSocialSchemePO> map = new HashMap<>();
        if (baseInfoPOS.size() > 0) {
            //遍历待更新的福利档案数据，对每组档案生成基数调整记录（基数单元未变化则忽略）
            for (InsuranceArchivesBaseInfoPO po : baseInfoPOS) {
                List<InsuranceArchivesSocialSchemePO> archiveList = getSocialSchemeMapper().getSocialByEmployeeIdAndPayOrg(InsuranceArchivesEmployeePO.builder()
                        .paymentOrganization(po.getPaymentOrganization()).employeeId(po.getEmployeeId()).build());
                if (archiveList.size() == 1) {
                    //新增调整记录，变更
                    encryptUtil.decryptList(archiveList, InsuranceArchivesSocialSchemePO.class);
                    map.put(po.getPaymentOrganization() + "-" + po.getEmployeeId(), archiveList.get(0));
                } else if (archiveList.size() > 1) {
                    throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"社保档案存在冗余数据！"));
                }
            }
        }
        return map;
    }
    private Map<String, InsuranceArchivesFundSchemePO> getFundArchiveMap(List<InsuranceArchivesBaseInfoPO> baseInfoPOS) {
        Map<String, InsuranceArchivesFundSchemePO> map = new HashMap<>();
        if (baseInfoPOS.size() > 0) {
            //遍历待更新的福利档案数据，对每组档案生成基数调整记录（基数单元未变化则忽略）
            for (InsuranceArchivesBaseInfoPO po : baseInfoPOS) {
                List<InsuranceArchivesFundSchemePO> archiveList = getFundSchemeMapper().getFundByEmployeeIdAndPayOrg(InsuranceArchivesEmployeePO.builder()
                        .paymentOrganization(po.getPaymentOrganization()).employeeId(po.getEmployeeId()).build());
                if (archiveList.size() == 1) {
                    //新增调整记录，变更
                    encryptUtil.decryptList(archiveList, InsuranceArchivesFundSchemePO.class);
                    map.put(po.getPaymentOrganization() + "-" + po.getEmployeeId(), archiveList.get(0));
                } else if (archiveList.size() > 1) {
                    throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"公积金档案存在冗余数据！"));
                }
            }
        }
        return map;
    }
    private Map<String, InsuranceArchivesOtherSchemePO> getOtherArchiveMap(List<InsuranceArchivesBaseInfoPO> baseInfoPOS) {
        Map<String, InsuranceArchivesOtherSchemePO> map = new HashMap<>();
        if (baseInfoPOS.size() > 0) {
            //遍历待更新的福利档案数据，对每组档案生成基数调整记录（基数单元未变化则忽略）
            for (InsuranceArchivesBaseInfoPO po : baseInfoPOS) {
                List<InsuranceArchivesOtherSchemePO> archiveList = getOtherSchemeMapper().getOtherByEmployeeIdAndPayOrg(InsuranceArchivesEmployeePO.builder()
                        .paymentOrganization(po.getPaymentOrganization()).employeeId(po.getEmployeeId()).build());
                if (archiveList.size() == 1) {
                    //新增调整记录，变更
                    encryptUtil.decryptList(archiveList, InsuranceArchivesOtherSchemePO.class);
                    map.put(po.getPaymentOrganization() + "-" + po.getEmployeeId(), archiveList.get(0));
                } else if (archiveList.size() > 1) {
                    throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"社保档案存在冗余数据！"));
                }
            }
        }
        return map;
    }


    /**
     * 导出档案导入所需要的模板，可根据开关选择是否导出现有的档案数据
     *
     * @param param 是否导出带档案数据的模板
     */
    @Override
    public XSSFWorkbook exportTemplate(InsuranceArchivesListParam param) {
        return getSIImportService().exportTemplate(param);

    }


    /**
     * 校验待新增的社保福利档案数据
     */
    @Override
    public Map<String, Object> checkSIArchiveAdd(SIArchiveImportParam param) {
        param.setAddData(false);
        return processAddSIArchive(param);
    }

    /**
     * 新增社保福利档案
     */
    @Override
    public Map<String, Object> addSIArchive(SIArchiveImportParam param) {
        param.setAddData(true);
        return processAddSIArchive(param);
    }

    private Map<String, Object> processAddSIArchive(SIArchiveImportParam param) {

        ValidUtil.doValidator(param);
        param.setProcess(true);

        if (StringUtils.isBlank(param.getRunStatus())) {
            throw new SalaryRunTimeException("福利档案执行状态未在导入条件设置中添加！");
        }
//        List<ExcelSheet> excelSheets = message.getBatchFile().getExcelSheets();
        // 租户key
//        String tenantKey = message.getTenantKey().toLowerCase();
        //操作员id
        Long creator = (long) user.getUID();
        //获取所有福利类型的id-name结合
        Map<String, Long> schemeNameIdMap = schemeNameIdMap();
        Map<Long, String> welfareMap = welfareMap();

        // 获取所有个税扣缴义务人的名称和id的map
        Map<String, Long> paymentNameIdMap = getTaxAgentService().listAll().stream().collect(Collectors.toMap(TaxAgentPO::getName, TaxAgentPO::getId));

        //获取所有个税扣缴义务人树型
        List<TaxAgentManageRangeEmployeeDTO> taxAgentManageRangeEmployeeTree = getTaxAgentService().listTaxAgentAndEmployeeTree();

        // 获取所有人员信息
        List<DataCollectionEmployee> employeeByIds = getSalaryEmployeeService(user).listEmployee();
        int total = 0;

        int index = 0;
        int successCount = 0;
        int errorCount = 0;

        // 待导入数据
        List<InsuranceArchivesAccountPO> insuranceArchivesAccountPOS = new ArrayList<>();

        // 待导入数据
        InputStream fileInputStream = null;
        try {
            // 表头
            List<String> headers = new ArrayList<>();
            if (param.getImportDatas().size() > 0) {
                Map<String, Object> getHeadersMap = param.getImportDatas().get(0);
                for (Map.Entry<String, Object> entry : getHeadersMap.entrySet()) {
                    headers.add(entry.getKey());
                }
            } else {
                throw new SalaryRunTimeException("新增福利档案数据为空！");
            }

            // 错误sheet数据
            List<Map<String, Object>> errorData = new LinkedList<>();
            // 错误提示
            List<Map<String, String>> excelComments = new LinkedList<>();

            // 处理数值
            List<Map<String, Object>> data = param.getImportDatas();
            total = data.size();

            //当前sheel的单行记录
            Map<String, Object> map;
            for (int i = 0; i < data.size(); i++) {
                index += 1;
                map = data.get(i);
                boolean isError;
                List<Map<String, Object>> singleAccount = new ArrayList<>();
                for (int j = 0; j < headers.size(); j++) {
                    //组装单条数据基础数据
                    String key = headers.get(j);
                    if (key == null) {
                        continue;
                    }
                    Map<String, Object> cellData = new HashMap<>();
                    cellData.put(key.toString(), Optional.ofNullable(map.get(key.toString())).orElse("").toString());
                    cellData.put("index", j);
                    singleAccount.add(cellData);
                }

                isError = singleAccountCheck(singleAccount, welfareMap, insuranceArchivesAccountPOS, employeeByIds, excelComments, errorCount + 1, schemeNameIdMap, paymentNameIdMap, creator, i + 2, taxAgentManageRangeEmployeeTree, param);
                if (isError) {
                    errorCount += 1;
                    // 添加错误数据
                    errorData.add(map);
                } else {
                    successCount += 1;
                }
//                salaryBatchService.sendImportRate(message.getBizId(), total, index);
            }

            // 如果sheet包含错误数据
//            if (CollectionUtils.isNotEmpty(errorData)) {
//                salaryBatchService.createErrorExcelSheet(headers, errorData, excelSheet.getName(), excelComments, errorExcelSheets);
//            }

            // 数据入库处理
            if (param.isAddData()) {
                handleImportData(insuranceArchivesAccountPOS, param);
            }
            // 发送导入回调信息
//        salaryBatchService.sendImportCallBackInfo(message, successCount, errorCount, errorExcelSheets);

            Map<String, Object> apidatas = new HashMap<String, Object>();
            apidatas.put("successCount", successCount);
            apidatas.put("errorCount", errorCount);
            apidatas.put("errorData", excelComments);
            return apidatas;
        } finally {
            IOUtils.closeQuietly(fileInputStream);
        }
    }

    @Override
    public List<String> updateSchemeDetail(List<InsuranceSchemeDetailUpdateParam> schemeDetailList) {
        List<String> errorInfo = new ArrayList<>();
        if (schemeDetailList.size() > 0) {
            log.info("待处理方明明细数量:{}", schemeDetailList.size());
            List<InsuranceSchemeDetailUpdateParam> toDealSchemeDetailList = schemeDetailList.stream().filter(f -> f.getPrimaryId() != null).collect(Collectors.toList());
            log.info("未设置方案id的方明明细无法处理，数量:{}", schemeDetailList.size() - toDealSchemeDetailList.size());

            //按照方案id分组
            Map<Long, List<InsuranceSchemeDetailUpdateParam>> schemeDetailMap = toDealSchemeDetailList
                    .stream().collect(Collectors.groupingBy(InsuranceSchemeDetailUpdateParam::getPrimaryId));

            schemeDetailMap.forEach((k, v) -> {
                updateSchemeDetailByPrimaryId(k, v, errorInfo);
            });

        }
        return errorInfo;
    }

    public List<String> updateSchemeDetailByPrimaryId(Long primaryId, List<InsuranceSchemeDetailUpdateParam> schemeDetailList, List<String> errorInfo) {
        try {
            Map<String, InsuranceSchemeDetailUpdateParam> schemeDetailUpdateMap = new HashMap<>();
            schemeDetailList.forEach(f -> {
                schemeDetailUpdateMap.put(f.getInsuranceId() + "-" + f.getPaymentScope(), f);
            });
//            List<InsuranceSchemeDetailPO> schemeDetailPOS = siSchemeBiz.listByPrimaryId(primaryId);
            List<InsuranceSchemeDetailPO> schemeDetailPOS = listByPrimaryId(primaryId);
            //替换修改字段
            if (schemeDetailPOS.size() > 0) {
                schemeDetailPOS.forEach(f -> {
                    if (schemeDetailUpdateMap.get(f.getInsuranceId() + "-" + f.getPaymentScope()) != null) {
                        InsuranceSchemeDetailUpdateParam schemeDetailUpdateParam = schemeDetailUpdateMap.get(f.getInsuranceId() + "-" + f.getPaymentScope());
                        BeanUtils.copyProperties(schemeDetailUpdateParam, f);
                        f.setUpdateTime(new Date());
                    }
                });
                encryptUtil.encryptList(schemeDetailPOS, InsuranceSchemeDetailPO.class);
                schemeDetailPOS.forEach(getInsuranceSchemeDetailMapper()::updateAll);

            } else {
                errorInfo.add("方案id:" + primaryId + "," + "表中不存在方案明细数据");
            }
        } catch (Exception e) {
            errorInfo.add("方案id:" + primaryId + "," + e.getMessage());
        }
        return errorInfo;
    }
    /*****以下代码为SISchemeBiz中逻辑迁移，旨在减少Biz类的使用*****/

    /**
     * 获取社保方案
     *
     * @param id
     * @param welfareTypeEnum
     * @return
     */
    public InsuranceSchemeFormVO getForm(Long id, WelfareTypeEnum welfareTypeEnum) {
        InsuranceSchemeDTO insuranceSchemeDTO = getSchemeFormDTO(welfareTypeEnum, id);
        List<InsuranceSchemeDetailDTO> insuranceSchemeDetailDTOList = getSchemeDetailFormDTO(welfareTypeEnum, id);
        return InsuranceSchemeFormVO.builder().schemeBatch(insuranceSchemeDTO).schemeDetailList(insuranceSchemeDetailDTOList).build();
    }

    /**
     * 获取方案主表信息 新建|详情
     *
     * @param welfareTypeEnum 福利类型
     * @param id              方案主键id
     * @return form
     */
    private InsuranceSchemeDTO getSchemeFormDTO(WelfareTypeEnum welfareTypeEnum, Long id) {
        InsuranceSchemeDTO insuranceSchemeDTO = InsuranceSchemeDTO.builder().paymentType(PaymentTypeEnum.SCHEME_TOWN).welfareType(welfareTypeEnum).build();
        if (id != null) {
            InsuranceSchemePO insuranceSchemePO = getById(id);
            SalaryAssert.notNull(insuranceSchemePO, SalaryI18nUtil.getI18nLabel(0,"福利方案不存在"));
            //BeanUtils.copyProperties(insuranceSchemePO, insuranceSchemeDTO);
            insuranceSchemeDTO.setId(insuranceSchemePO.getId());
            insuranceSchemeDTO.setPaymentArea(insuranceSchemePO.getPaymentArea());
            insuranceSchemeDTO.setRemarks(insuranceSchemePO.getRemarks());
            insuranceSchemeDTO.setSchemeName(insuranceSchemePO.getSchemeName());
            insuranceSchemeDTO.setPaymentType(SalaryEnumUtil.enumMatchByValue(insuranceSchemePO.getPaymentType(), PaymentTypeEnum.values(), PaymentTypeEnum.class));
            insuranceSchemeDTO.setWelfareType(welfareTypeEnum);
            insuranceSchemeDTO.setSharedType(StringUtils.isBlank(insuranceSchemePO.getSharedType()) ? "0" : insuranceSchemePO.getSharedType());
            insuranceSchemeDTO.setTaxAgentIds(insuranceSchemePO.getTaxAgentIds());
        }
        return insuranceSchemeDTO;
    }

    /**
     * 获取方案明细表集合 新建|详情
     *
     * @param welfareTypeEnum 福利类型
     * @param id              方案主键id
     * @return form
     */
    public List<InsuranceSchemeDetailDTO> getSchemeDetailFormDTO(WelfareTypeEnum welfareTypeEnum, Long id) {
        List<ICategoryPO> insuranceCategoryPOS = listByWelfareType(welfareTypeEnum.getValue());
        List<InsuranceSchemeDetailDTO> insuranceSchemeDetailDTOList = new ArrayList<>();
        insuranceCategoryPOS.forEach(item -> {
            PaymentScopeEnum[] paymentScopeEnums = SalaryEnumUtil.stringToEnums(item.getPaymentScope(), ",");
            Arrays.stream(paymentScopeEnums).forEach(e -> {
                InsuranceSchemeDetailDTO insuranceSchemeDetailDTO = InsuranceSchemeDetailDTO.builder().build();
                InsuranceSchemeDetailPO insuranceSchemeDetailPO = getByPPI(id, e.getValue(), item.getId());
                if (insuranceSchemeDetailPO == null) {
                    insuranceSchemeDetailDTO = InsuranceSchemeDetailDTO.builder()
                            .id((long) (Math.random() * 10000))
                            .insuranceId(item.getId())
                            .insuranceName(item.getInsuranceName())
                            .paymentScope(e.getDefaultLabel())
                            .rententionRule(String.valueOf(SalaryRoundingModeEnum.ROUNDING.getValue()))
                            .validNum(2)
                            .cycleSetting("000000000000")
                            .paymentCycle("0")
                            .accountType("0")
                            .build();
                    if (Objects.equals(item.getDataType(), DataTypeEnum.SYSTEM.getValue())) {
                        insuranceSchemeDetailDTO.setIsPayment(true);
                    } else {
                        insuranceSchemeDetailDTO.setIsPayment(false);
                    }
                } else {
                    //BeanUtils.copyProperties(insuranceSchemeDetailPO, insuranceSchemeDetailDTO);
                    insuranceSchemeDetailDTO.setEffectiveTime(insuranceSchemeDetailPO.getEffectiveTime());
                    insuranceSchemeDetailDTO.setExpirationTime(insuranceSchemeDetailPO.getExpirationTime());
                    insuranceSchemeDetailDTO.setId(insuranceSchemeDetailPO.getId());
                    insuranceSchemeDetailDTO.setInsuranceId(insuranceSchemeDetailPO.getInsuranceId());
                    insuranceSchemeDetailDTO.setPaymentScopeValue(insuranceSchemeDetailPO.getPaymentScope());
                    insuranceSchemeDetailDTO.setPrimaryId(insuranceSchemeDetailPO.getPrimaryId());
                    insuranceSchemeDetailDTO.setValidNum(insuranceSchemeDetailPO.getValidNum() == null ? 2 : insuranceSchemeDetailPO.getValidNum());

                    if (insuranceSchemeDetailPO.getIsPayment() != null) {
                        insuranceSchemeDetailDTO.setIsPayment(Objects.equals(insuranceSchemeDetailPO.getIsPayment(), IsPaymentEnum.YES.getValue()));
                    }
                    if (insuranceSchemeDetailPO.getPaymentCycle() != null) {
                        insuranceSchemeDetailDTO.setPaymentCycle(insuranceSchemeDetailPO.getPaymentCycle() + "");
                    } else {
                        insuranceSchemeDetailDTO.setPaymentCycle("0");
                    }
                    if (insuranceSchemeDetailPO.getAccountType() != null) {
                        insuranceSchemeDetailDTO.setAccountType(insuranceSchemeDetailPO.getAccountType() + "");
                    } else {
                        insuranceSchemeDetailDTO.setAccountType("0");
                    }
                    if (insuranceSchemeDetailPO.getCycleSetting() == null) {
                        insuranceSchemeDetailDTO.setCycleSetting("000000000000");
                    } else {
                        insuranceSchemeDetailDTO.setCycleSetting(insuranceSchemeDetailPO.getCycleSetting());
                    }
                    if (StringUtils.isNotBlank(insuranceSchemeDetailPO.getUpperLimit())) {
                        BigDecimal bigDecimal = new BigDecimal(insuranceSchemeDetailPO.getUpperLimit());
                        insuranceSchemeDetailDTO.setUpperLimit(numberCheck(bigDecimal.toPlainString()) ? null : bigDecimal);
                    }
                    if (StringUtils.isNotBlank(insuranceSchemeDetailPO.getLowerLimit())) {
                        BigDecimal bigDecimal = new BigDecimal(insuranceSchemeDetailPO.getLowerLimit());
                        insuranceSchemeDetailDTO.setLowerLimit(numberCheck(bigDecimal.toPlainString()) ? null : bigDecimal);
                    }
                    if (StringUtils.isNotBlank(insuranceSchemeDetailPO.getPaymentProportion())) {
                        BigDecimal bigDecimal = new BigDecimal(insuranceSchemeDetailPO.getPaymentProportion());
                        insuranceSchemeDetailDTO.setPaymentProportion(numberCheck(bigDecimal.toPlainString()) ? null : bigDecimal);
                    }
                    if (StringUtils.isNotBlank(insuranceSchemeDetailPO.getFixedCost())) {
                        BigDecimal bigDecimal = new BigDecimal(insuranceSchemeDetailPO.getFixedCost());
                        insuranceSchemeDetailDTO.setFixedCost(numberCheck(bigDecimal.toPlainString()) ? null : bigDecimal);
                    }
                    insuranceSchemeDetailDTO.setInsuranceName(item.getInsuranceName());
                    insuranceSchemeDetailDTO.setRententionRule(String.valueOf(insuranceSchemeDetailPO.getRententionRule()));
                    insuranceSchemeDetailDTO.setPaymentScope(e.getDefaultLabel());

                }
                insuranceSchemeDetailDTO.setPaymentScopeValue(e.getValue());
                insuranceSchemeDetailDTOList.add(insuranceSchemeDetailDTO);
            });
        });
        return insuranceSchemeDetailDTOList;
    }

    /**
     * 社保方案基础信息主表
     *
     * @param id
     * @return
     */
    public InsuranceSchemePO getById(Long id) {

        InsuranceSchemePO insuranceSchemePO = getInsuranceSchemeMapper().getById(id);
        return insuranceSchemePO;
    }

    /**
     * 根据福利类型获取
     *
     * @param welfareType
     * @return
     */
    public List<ICategoryPO> listByWelfareType(Integer welfareType) {

        List<ICategoryPO> insuranceCategoryPOS = getICategoryMapper().listByWelfareType(welfareType, null);
        return insuranceCategoryPOS;
    }

    public boolean numberCheck(String number) {
        return Pattern.compile("^0\\.[0]*").matcher(number).matches();
    }

    private InsuranceSchemeDetailPO getByPPI(Long primaryId, Integer paymentScope, Long insuranceId) {

        InsuranceSchemeDetailPO insuranceSchemeDetailPO = getInsuranceSchemeDetailMapper().getByPPI(primaryId, paymentScope, insuranceId);
        encryptUtil.decrypt(insuranceSchemeDetailPO, InsuranceSchemeDetailPO.class);
        return insuranceSchemeDetailPO;

    }

    /**
     * 新增
     *
     * @param saveParam
     * @param employeeId
     */
    public void save(InsuranceSchemeReqParam saveParam, long employeeId) {

        //保存福利项目主表
        saveParam.getInsuranceScheme().setSchemeName(StringUtils.trim(saveParam.getInsuranceScheme().getSchemeName()));
        List<InsuranceSchemePO> listResult = getInsuranceSchemeMapper().listByName(saveParam.getInsuranceScheme().getSchemeName());
        SalaryAssert.isEmpty(listResult, SalaryI18nUtil.getI18nLabel(0,"该福利名称已经存在,福利名称系统全局唯一"));

        InsuranceSchemePO insuranceSchemePO = InsuranceSchemeBO.convert2BatchPO(saveParam.getInsuranceScheme(), employeeId);
        if (insuranceSchemePO.getSharedType() == null) {
            insuranceSchemePO.setSharedType(SharedTypeEnum.PUBLIC.getValue());
        } else {
            if (insuranceSchemePO.getSharedType().equals(SharedTypeEnum.PRIVATE.getValue()) && StringUtils.isBlank(insuranceSchemePO.getTaxAgentIds())) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"方案可见性为私有时，未设置可见范围"));
            }
        }
        getInsuranceSchemeMapper().insert(insuranceSchemePO);
        //记录操作日志
        List<InsuranceSchemePO> schemePOList = getInsuranceSchemeMapper().listByName(insuranceSchemePO.getSchemeName());
        InsuranceSchemePO targetPO = new InsuranceSchemePO();
        if (schemePOList != null && schemePOList.size() > 0) {
            targetPO = schemePOList.get(0);
            LoggerContext<InsuranceSchemePO> loggerContext = new LoggerContext<>();
            loggerContext.setUser(user);
            loggerContext.setTargetId(String.valueOf(targetPO.getId()));
            loggerContext.setTargetName(targetPO.getSchemeName());
            loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
            loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "新增福利方案主表"));
            loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案基础信息") + ": " + targetPO.getSchemeName());
            loggerContext.setNewValues(targetPO);
            SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
        }
        //保存福利项目明细表
        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = InsuranceSchemeBO.convertToInsuranceSchemeDetailPoList(saveParam.getInsuranceSchemeDetailList(), employeeId, insuranceSchemePO.getId());
        //加密入库
        encryptUtil.encryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
        insuranceSchemeDetailPOS.forEach(getInsuranceSchemeDetailMapper()::insert);
        //记录明细表操作日志
        if (insuranceSchemeDetailPOS.size() > 0) {
            encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);

            LoggerContext<InsuranceSchemeDetailPO> loggerContext = new LoggerContext<>();
            loggerContext.setUser(user);
            loggerContext.setTargetId(String.valueOf(targetPO.getId()));
            loggerContext.setTargetName(targetPO.getSchemeName());
            loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
            loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "新增福利方案明细表"));
            loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案明细"));
            insuranceSchemeDetailPOS.forEach(loggerContext::setNewValues);
            SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
        }

    }

    /**
     * 更新
     *
     * @param updateParam
     * @param employeeId
     */
    public String update(InsuranceSchemeReqParam updateParam, long employeeId) {
        //查询是否存在福利方案
        InsuranceSchemePO insuranceSchemePO = getById(updateParam.getInsuranceScheme().getId());
        if (Objects.isNull(insuranceSchemePO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"福利方案不存在"));
        }
        //去除入参中方案名称的空格
        updateParam.getInsuranceScheme().setSchemeName(StringUtils.trim(updateParam.getInsuranceScheme().getSchemeName()));
        //福利方案名称重复
        List<InsuranceSchemePO> insuranceSchemePOList = getInsuranceSchemeMapper().listByName(updateParam.getInsuranceScheme().getSchemeName());
        if (CollectionUtils.isNotEmpty(insuranceSchemePOList)) {
            boolean repeat = insuranceSchemePOList.stream().anyMatch(item -> !Objects.equals(item.getId(), updateParam.getInsuranceScheme().getId()));
            SalaryAssert.isTrue(!repeat, SalaryI18nUtil.getI18nLabel(0,"福利方案名称重复"));
        }

        if (insuranceSchemePO.getSharedType() == null) {
            insuranceSchemePO.setSharedType(SharedTypeEnum.PUBLIC.getValue());
        } else {
            if (insuranceSchemePO.getSharedType().equals(SharedTypeEnum.PRIVATE.getValue()) && StringUtils.isBlank(insuranceSchemePO.getTaxAgentIds())) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"方案可见性为私有时，未设置可见范围"));
            }
        }
        //记录主表操作日志
        LoggerContext<InsuranceSchemePO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(insuranceSchemePO.getId().toString());
        loggerContext.setTargetName(insuranceSchemePO.getSchemeName());
        loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "修改福利方案主表"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案基础信息") + ": " + insuranceSchemePO.getSchemeName());
//        loggerContext.setOldValues(insuranceSchemePO);
        //更新福利方案主表
        InsuranceSchemePO insuranceSchemePO1 = InsuranceSchemeBO.buildInsuranceSchemePO(insuranceSchemePO, updateParam.getInsuranceScheme());
        getInsuranceSchemeMapper().update(insuranceSchemePO1);
        //记录主表操作日志
        loggerContext.setNewValues(insuranceSchemePO1);
        SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
        // 查询原本的福利明细信息
        List<InsuranceSchemeDetailPO> oldInsuranceSchemeDetails = getInsuranceSchemeDetailMapper().queryInsuranceSchemeDetailList(updateParam.getInsuranceScheme().getId(), IsPaymentEnum.YES.getValue());
        // 本次福利明细
        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = InsuranceSchemeBO.convertToInsuranceSchemeDetailPoList(updateParam.getInsuranceSchemeDetailList(), employeeId, insuranceSchemePO.getId());

        StringBuilder baseLimitStrBuilder = new StringBuilder();
        if (updateParam.getValidate() || updateParam.getChangeData()) {
            // 查询本次修改了哪些类型的上下限
            List<InsuranceSchemeDetailPO> schemeDetailChangeLimitList = getChanceLimitSchemeDetailList(oldInsuranceSchemeDetails, insuranceSchemeDetailPOS);
            // 对于不满足上下限的基数进行自动调整
            autoAdjustBaseByLimit(updateParam, schemeDetailChangeLimitList, insuranceSchemePO, baseLimitStrBuilder);
            if (updateParam.getValidate() && StringUtils.isNotBlank(baseLimitStrBuilder.toString())) {
                // 是校验且存在校验不通过的档案，返回前端确认
                return baseLimitStrBuilder.toString();
            }
        }

        //更新福利方案明细表 先删后插
        getInsuranceSchemeDetailMapper().batchDeleteByPrimaryIds(Collections.singleton(updateParam.getInsuranceScheme().getId()));
        //更新明细表
        encryptUtil.encryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
        insuranceSchemeDetailPOS.forEach(getInsuranceSchemeDetailMapper()::insert);

        //记录明细表操作日志
        encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
        LoggerContext<InsuranceSchemeDetailPO> insuranceSchemeDetailContext = new LoggerContext<>();
        insuranceSchemeDetailContext.setUser(user);
        insuranceSchemeDetailContext.setTargetId(String.valueOf(insuranceSchemePO.getId()));
        insuranceSchemeDetailContext.setTargetName(insuranceSchemePO.getSchemeName());
        insuranceSchemeDetailContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
        insuranceSchemeDetailContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "修改福利方案明细表"));
        insuranceSchemeDetailContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案明细"));
        insuranceSchemeDetailPOS.forEach(insuranceSchemeDetailContext::setNewValues);
        SalaryElogConfig.siSchemeLoggerTemplate.write(insuranceSchemeDetailContext);
        return "success";
    }

    /**
     * 对于不满足上下限的基数进行自动调整
     * @param schemeDetailChangeLimitList
     * @param insuranceSchemePO
     */
    private void autoAdjustBaseByLimit(InsuranceSchemeReqParam updateParam, List<InsuranceSchemeDetailPO> schemeDetailChangeLimitList, InsuranceSchemePO insuranceSchemePO, StringBuilder baseLimitStrBuilder) {
        Map<Integer, List<InsuranceSchemeDetailPO>> insuranceSchemeDetailMap = SalaryEntityUtil.group2Map(schemeDetailChangeLimitList, InsuranceSchemeDetailPO::getPaymentScope);
        List<InsuranceSchemeDetailPO> personChangeDeatilList = insuranceSchemeDetailMap.getOrDefault(PaymentScopeEnum.SCOPE_PERSON.getValue(), Collections.emptyList());
        List<InsuranceSchemeDetailPO> companyChangeDetailList = insuranceSchemeDetailMap.getOrDefault(PaymentScopeEnum.SCOPE_COMPANY.getValue(), Collections.emptyList());
        List<String> runStatus = Arrays.asList(EmployeeStatusEnum.STAY_DEL.getValue(), EmployeeStatusEnum.PAYING.getValue(), EmployeeStatusEnum.STAY_DEL.getValue());
        // 获取该方案下的社保福利档案
        Integer welfareType = insuranceSchemePO.getWelfareType();
        if (welfareType.equals(WelfareTypeEnum.SOCIAL_SECURITY.getValue())) {
            List<InsuranceArchivesSocialSchemePO> needUpdateSocialArchiveList = new ArrayList<>();
            List<InsuranceArchivesSocialSchemePO> insuranceArchivesSocialSchemePOS = getSocialSchemeMapper().listBySchemeId(insuranceSchemePO.getId(), runStatus);
            encryptUtil.decryptList(insuranceArchivesSocialSchemePOS, InsuranceArchivesSocialSchemePO.class);
            // 获取人员信息
            List<Long> empIds = insuranceArchivesSocialSchemePOS.stream().map(InsuranceArchivesSocialSchemePO::getEmployeeId).collect(Collectors.toList());
            List<DataCollectionEmployee> employeeList = getSalaryEmployeeService(user).listByIds(empIds);
            Map<Long, DataCollectionEmployee> employeeMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId);
            // 社保
            insuranceArchivesSocialSchemePOS.forEach(archive -> {
                Boolean[] changeFlag = {false};
                // 个人调整
                String socialPaymentBaseString = archive.getSocialPaymentBaseString();
                if (CollectionUtils.isNotEmpty(personChangeDeatilList)) {
                    socialPaymentBaseString = adaptWelBaseLimit(socialPaymentBaseString, personChangeDeatilList, changeFlag);
                }
                // 公司调整
                String socialPaymentComBaseString = archive.getSocialPaymentComBaseString();
                if (CollectionUtils.isNotEmpty(companyChangeDetailList)) {
                    socialPaymentComBaseString = adaptWelBaseLimit(socialPaymentComBaseString, companyChangeDetailList, changeFlag);
                }
                if (changeFlag[0]) {
                    DataCollectionEmployee employee = employeeMap.get(archive.getEmployeeId());
                    baseLimitStrBuilder.append(employee == null ? archive.getEmployeeId() : employee.getUsername() + "\n");
                    archive.setSocialPaymentBaseString(socialPaymentBaseString);
                    archive.setSocialPaymentComBaseString(socialPaymentComBaseString);
                    needUpdateSocialArchiveList.add(archive);
                    if (updateParam.getChangeData() && CollectionUtils.isNotEmpty(needUpdateSocialArchiveList)) {
                        // 更新
                        encryptUtil.encrypt(archive, InsuranceArchivesSocialSchemePO.class);
                        getSocialSchemeMapper().updateById(archive);
                    }
                }
            });
        } else if (welfareType.equals(WelfareTypeEnum.ACCUMULATION_FUND.getValue())) {
            List<InsuranceArchivesFundSchemePO> needUpdateFundArchiveList = new ArrayList<>();
            List<InsuranceArchivesFundSchemePO> insuranceArchivesFundSchemePOS = getFundSchemeMapper().listBySchemeId(insuranceSchemePO.getId(), runStatus);
            encryptUtil.decryptList(insuranceArchivesFundSchemePOS, InsuranceArchivesFundSchemePO.class);
            // 获取人员信息
            List<Long> empIds = insuranceArchivesFundSchemePOS.stream().map(InsuranceArchivesFundSchemePO::getEmployeeId).collect(Collectors.toList());
            List<DataCollectionEmployee> employeeList = getSalaryEmployeeService(user).listByIds(empIds);
            Map<Long, DataCollectionEmployee> employeeMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId);
            // 公积金
            insuranceArchivesFundSchemePOS.forEach(archive -> {
                Boolean[] changeFlag = {false};
                // 个人调整
                String fundPaymentBaseString = archive.getFundPaymentBaseString();
                if (CollectionUtils.isNotEmpty(personChangeDeatilList)) {
                    fundPaymentBaseString = adaptWelBaseLimit(fundPaymentBaseString, personChangeDeatilList, changeFlag);
                }
                // 公司调整
                String fundPaymentComBaseString = archive.getFundPaymentComBaseString();
                if (CollectionUtils.isNotEmpty(companyChangeDetailList)) {
                    fundPaymentComBaseString = adaptWelBaseLimit(fundPaymentComBaseString, companyChangeDetailList, changeFlag);
                }
                if (changeFlag[0]) {
                    DataCollectionEmployee employee = employeeMap.get(archive.getEmployeeId());
                    baseLimitStrBuilder.append(employee == null ? archive.getEmployeeId() : employee.getUsername() + "\n");
                    archive.setFundPaymentBaseString(fundPaymentBaseString);
                    archive.setFundPaymentComBaseString(fundPaymentComBaseString);
                    needUpdateFundArchiveList.add(archive);
                    if (updateParam.getChangeData() && CollectionUtils.isNotEmpty(needUpdateFundArchiveList)) {
                        // 更新
                        encryptUtil.encrypt(archive, InsuranceArchivesFundSchemePO.class);
                        getFundSchemeMapper().updateById(archive);
                    }
                }
            });
        } else if (welfareType.equals(WelfareTypeEnum.OTHER.getValue())) {
            List<InsuranceArchivesOtherSchemePO> insuranceArchivesOtherSchemePOS = getOtherSchemeMapper().listBySchemeId(insuranceSchemePO.getId(), runStatus);
            encryptUtil.decryptList(insuranceArchivesOtherSchemePOS, InsuranceArchivesOtherSchemePO.class);
            List<InsuranceArchivesOtherSchemePO> needUpdateOtherArchiveList = new ArrayList<>();
            // 获取人员信息
            List<Long> empIds = insuranceArchivesOtherSchemePOS.stream().map(InsuranceArchivesOtherSchemePO::getEmployeeId).collect(Collectors.toList());
            List<DataCollectionEmployee> employeeList = getSalaryEmployeeService(user).listByIds(empIds);
            Map<Long, DataCollectionEmployee> employeeMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId);
            // 企业年金或其他福利
            insuranceArchivesOtherSchemePOS.forEach(archive -> {
                Boolean[] changeFlag = {false};
                // 个人调整
                String otherPaymentBaseString = archive.getOtherPaymentBaseString();
                if (CollectionUtils.isNotEmpty(personChangeDeatilList)) {
                    otherPaymentBaseString = adaptWelBaseLimit(otherPaymentBaseString, personChangeDeatilList, changeFlag);
                }
                // 公司调整的
                String otherPaymentComBaseString = archive.getOtherPaymentComBaseString();
                if (CollectionUtils.isNotEmpty(companyChangeDetailList)) {
                    otherPaymentComBaseString = adaptWelBaseLimit(otherPaymentComBaseString, companyChangeDetailList, changeFlag);
                }
                if (changeFlag[0]) {
                    DataCollectionEmployee employee = employeeMap.get(archive.getEmployeeId());
                    baseLimitStrBuilder.append(employee == null ? archive.getEmployeeId() : employee.getUsername() + "\n");
                    archive.setOtherPaymentBaseString(otherPaymentBaseString);
                    archive.setOtherPaymentComBaseString(otherPaymentComBaseString);
                    needUpdateOtherArchiveList.add(archive);
                    if (updateParam.getChangeData() && CollectionUtils.isNotEmpty(needUpdateOtherArchiveList)) {
                        // 更新
                        encryptUtil.encrypt(archive, InsuranceArchivesOtherSchemePO.class);
                        getOtherSchemeMapper().updateById(archive);
                    }
                }
            });
        }
    }

    public String adaptWelBaseLimit(String paymentBaseString, List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOList, Boolean[] changeFlag) {

        if (paymentBaseString == null) {
            return null;
        }
        Map<String, String> paymentBaseJson = JSON.parseObject(paymentBaseString, new HashMap<String, String>().getClass());
        if (paymentBaseJson == null) {
            return null;
        }
        Map<Long, InsuranceSchemeDetailPO> insuranceSchemeDetailPOMap = SalaryEntityUtil.convert2Map(insuranceSchemeDetailPOList, InsuranceSchemeDetailPO::getInsuranceId);
        List<String> insuranceIdList = insuranceSchemeDetailPOList.stream().map(po -> po.getInsuranceId().toString()).collect(Collectors.toList());

        Set<String> paymentInsuranceIdList = paymentBaseJson.keySet();
        List<String> needAddInsuranceIds = insuranceIdList.stream().filter(insuranceId -> !paymentInsuranceIdList.contains(insuranceId)).collect(Collectors.toList());
        needAddInsuranceIds.stream().forEach(insuranceId -> {
            paymentBaseJson.put(insuranceId, "0.00");
        });

        for (Map.Entry<String, String> entry : paymentBaseJson.entrySet()) {

            //判断福利值是否为空/数字
            if (entry.getValue() == null || entry.getValue().length() == 0) {
                continue;
            } else if (!isNumeric(entry.getValue())) {
                log.info("福利值非数字！");
                continue;
                // throw new SalaryRunTimeException("福利值非数字");
            }

            if (!insuranceIdList.contains(entry.getKey())) {
                // 没有修改上下限
                continue;
            }
            InsuranceSchemeDetailPO insuranceSchemeDetailPO = insuranceSchemeDetailPOMap.get(Long.valueOf(entry.getKey()));
            if (insuranceSchemeDetailPO != null) {

                encryptUtil.decrypt(insuranceSchemeDetailPO, InsuranceSchemeDetailPO.class);
                String lowerLimit = "0.000".equals(insuranceSchemeDetailPO.getLowerLimit()) ? null : insuranceSchemeDetailPO.getLowerLimit();
                String upperLimit = "0.000".equals(insuranceSchemeDetailPO.getUpperLimit()) ? null : insuranceSchemeDetailPO.getUpperLimit();
                if (lowerLimit != null && lowerLimit.length() > 0 && Double.parseDouble(entry.getValue()) < Double.parseDouble(lowerLimit)) {
                    //数值低于对应福利明细下限
                    entry.setValue(lowerLimit);
                    changeFlag[0] = true;
                }
                if (upperLimit != null && upperLimit.length() > 0 && Double.parseDouble(entry.getValue()) > Double.parseDouble(upperLimit)) {
                    //数值高于对应福利明细上限
                    entry.setValue(upperLimit);
                    changeFlag[0] = true;
                }
            }
        }
        return JSON.toJSONString(paymentBaseJson);
    }

    /**
     * 判断字符串是否为整数或者小数或者负数
     */
    public static boolean isNumeric(String str){

        Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;

    }

    /**
     * 获取修改了哪些明细项的上限和下限
     * @param oldInsuranceSchemeDetails
     * @param newInsuranceSchemeDetails
     * @return
     */
    private List<InsuranceSchemeDetailPO> getChanceLimitSchemeDetailList(List<InsuranceSchemeDetailPO> oldInsuranceSchemeDetails, List<InsuranceSchemeDetailPO> newInsuranceSchemeDetails) {
        List<InsuranceSchemeDetailPO> schemeDetailChangeLimitList = new ArrayList<>();
        // key: 福利项id-缴纳范围
        Map<String, InsuranceSchemeDetailPO> oldInsuranceSchemeDetailMap = SalaryEntityUtil.convert2Map(oldInsuranceSchemeDetails, d -> d.getInsuranceId() + "-" + d.getPaymentScope());
        newInsuranceSchemeDetails.stream()
                .filter(detail -> detail.getIsPayment().equals(NumberUtils.INTEGER_ONE))
                .forEach(detail -> {
                    boolean changeFlag = false;
                    InsuranceSchemeDetailPO oldInsuranceSchemeDetailPO = oldInsuranceSchemeDetailMap.get(detail.getInsuranceId() + "-" + detail.getPaymentScope());
                    if (oldInsuranceSchemeDetailPO == null) {
                        changeFlag = true;
                    } else {
                        if (!oldInsuranceSchemeDetailPO.getUpperLimit().equals(detail.getUpperLimit())) {
                            changeFlag = true;
                        }
                        if (!oldInsuranceSchemeDetailPO.getLowerLimit().equals(detail.getLowerLimit())) {
                            changeFlag = true;
                        }
                    }
                    if (changeFlag) {
                        schemeDetailChangeLimitList.add(detail);
                    }
                });
        return schemeDetailChangeLimitList;
    }

    public int checkBeforeDeleteSocialscheme(Map<String, Object> params) {
        return getSIAccountUtilMapper().checkBeforeDeleteSocialscheme((Collection<Long>) params.get("ids")).get(0).getNum();
    }

    public int checkBeforeDeleteAccumulationfund(Map<String, Object> params) {
        return getSIAccountUtilMapper().checkBeforeDeleteAccumulationfund((Collection<Long>) params.get("ids")).get(0).getNum();
    }

    public int checkBeforeDeleteOtherscheme(Map<String, Object> params) {
        return getSIAccountUtilMapper().checkBeforeDeleteOtherscheme((Collection<Long>) params.get("ids")).get(0).getNum();
    }

    public int checkBeforeDeleteBill(Map<String, Object> params, Integer welfareTypeId) {
        return getSIAccountUtilMapper().checkBeforeDeleteBill((Collection<Long>) params.get("ids"), welfareTypeId).get(0).getNum();
    }

    public void deleteSocialscheme(Map<String, Object> params) {

        Collection<Long> schemeIds = (Collection<Long>) params.get("ids");
        List<InsuranceSchemePO> targetPoList = getInsuranceSchemeMapper().listBySchemeIds(schemeIds);
        List<InsuranceSchemeDetailPO> targetDetailPoList = getInsuranceSchemeDetailMapper().listBySchemeIds(schemeIds);
        getInsuranceSchemeMapper().deleteByIds(schemeIds);
        getInsuranceSchemeDetailMapper().deleteByIds(schemeIds);

        //记录操作日志
        Map<Long, List<InsuranceSchemeDetailPO>> targetDetailMap = targetDetailPoList.stream()
                .collect(Collectors.groupingBy(InsuranceSchemeDetailPO::getPrimaryId));
        if (targetPoList.size() > 0) {
            targetPoList.forEach(targetPO -> {
                //记录主表操作日志
                LoggerContext<InsuranceSchemePO> loggerContext = new LoggerContext<>();
                loggerContext.setUser(user);
                loggerContext.setTargetId(String.valueOf(targetPO.getId()));
                loggerContext.setTargetName(targetPO.getSchemeName());
                loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
                loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除福利方案主表"));
                loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除福利方案") + ": " + targetPO.getSchemeName());
                loggerContext.setNewValues(targetPO);
                SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
                //记录明细表操作日志
                List<InsuranceSchemeDetailPO> targetDetails = targetDetailMap.get(targetPO.getId());
                encryptUtil.decryptList(targetDetails, InsuranceSchemeDetailPO.class);
                if (targetDetails != null && targetDetails.size() > 0) {
                    LoggerContext<InsuranceSchemeDetailPO> detailLoggerContext = new LoggerContext<>();
                    detailLoggerContext.setUser(user);
                    detailLoggerContext.setTargetId(String.valueOf(targetPO.getId()));
                    detailLoggerContext.setTargetName(targetPO.getSchemeName());
                    detailLoggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
                    detailLoggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除福利方案明细"));
                    detailLoggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案明细"));
                    targetDetails.forEach(detailLoggerContext::setNewValues);
                    SalaryElogConfig.siSchemeLoggerTemplate.write(detailLoggerContext);
                }
            });
        }

    }

    /**
     * 复制方案
     *
     * @param id
     * @param schemeName
     * @param employeeId
     */
    public void copy(Long id, String schemeName, long employeeId) {
        //去除入参中方案名称的空格
        schemeName = StringUtils.trim(schemeName);
        List<InsuranceSchemePO> listResult = getInsuranceSchemeMapper().listByName(schemeName);
        SalaryAssert.isEmpty(listResult, SalaryI18nUtil.getI18nLabel(0,"方案名称重复"));
        if (Objects.isNull(id)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"方案id为空"));
        }
        if (Objects.isNull(schemeName)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"复制方案名为空"));
        }
        InsuranceSchemePO insuranceSchemePO = getById(id);
        if (Objects.isNull(insuranceSchemePO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"方案不存在"));
        }
        if (insuranceSchemePO.getSchemeName().equals(schemeName)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"方案名称重复"));
        }
        InsuranceSchemePO batchPO = InsuranceSchemePO.builder()
                .creator(employeeId)
                .createTime(new Date())
                .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                .schemeName(schemeName)
                .paymentArea(insuranceSchemePO.getPaymentArea())
                .updateTime(new Date())
                .deleteType(DeleteTypeEnum.NOT_DELETED.getValue())
                .paymentType(insuranceSchemePO.getPaymentType())
                .remarks(insuranceSchemePO.getRemarks())
                .welfareType(insuranceSchemePO.getWelfareType())
                .isUse(insuranceSchemePO.getIsUse())
                .build();
        getInsuranceSchemeMapper().insert(batchPO);
        //记录操作日志
        List<InsuranceSchemePO> schemePOList = getInsuranceSchemeMapper().listByName(insuranceSchemePO.getSchemeName());
        InsuranceSchemePO targetPO = new InsuranceSchemePO();
        if (schemePOList != null && schemePOList.size() > 0) {
            targetPO = schemePOList.get(0);
            LoggerContext<InsuranceSchemePO> loggerContext = new LoggerContext<>();
            loggerContext.setUser(user);
            loggerContext.setTargetId(String.valueOf(targetPO.getId()));
            loggerContext.setTargetName(targetPO.getSchemeName());
            loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
            loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "复制新增福利方案主表"));
            loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案基础信息") + ": " + targetPO.getSchemeName());
            loggerContext.setNewValues(targetPO);
            SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
        }
        List<InsuranceSchemeDetailPO> detailList = getInsuranceSchemeDetailMapper().queryListBySchemeId(id);
        detailList = encryptUtil.decryptList(detailList,InsuranceSchemeDetailPO.class);
        if (CollectionUtils.isNotEmpty(detailList)) {
            List<InsuranceSchemeDetailPO> detailPOS = detailList.stream().map(item -> InsuranceSchemeDetailPO.builder()
                    .creator(employeeId)
                    .createTime(new Date())
                    .deleteType(DeleteTypeEnum.NOT_DELETED.getValue())
                    .effectiveTime(item.getEffectiveTime())
                    .expirationTime(item.getExpirationTime())
                    .fixedCost(item.getFixedCost())
                    .insuranceId(item.getInsuranceId())
                    .isPayment(item.getIsPayment())
                    .lowerLimit(item.getLowerLimit())
                    .paymentScope(item.getPaymentScope())
                    .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                    .paymentProportion(item.getPaymentProportion())
                    .updateTime(new Date())
                    .primaryId(batchPO.getId())
                    .rententionRule(item.getRententionRule())
                    .upperLimit(item.getUpperLimit())
                    .validNum(item.getValidNum()==null?2:item.getValidNum())
                    .build()
            ).collect(Collectors.toList());

            //加密入库
            encryptUtil.encryptList(detailPOS, InsuranceSchemeDetailPO.class);
            detailPOS.forEach(getInsuranceSchemeDetailMapper()::insert);
            //记录明细表操作日志
            if (detailPOS.size() > 0) {
                encryptUtil.decryptList(detailPOS, InsuranceSchemeDetailPO.class);

                LoggerContext<InsuranceSchemeDetailPO> loggerContext = new LoggerContext<>();
                loggerContext.setUser(user);
                loggerContext.setTargetId(String.valueOf(targetPO.getId()));
                loggerContext.setTargetName(targetPO.getSchemeName());
                loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
                loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "复制新增福利方案明细表"));
                loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "福利方案明细"));
                detailPOS.forEach(loggerContext::setNewValues);
                SalaryElogConfig.siSchemeLoggerTemplate.write(loggerContext);
            }
        }

    }

    /**
     * 社保方案基础信息明细表
     *
     * @param primaryId
     * @return
     */
    public List<InsuranceSchemeDetailPO> listByPrimaryId(Long primaryId) {

        List<InsuranceSchemeDetailPO> insuranceSchemeDetailPOS = getInsuranceSchemeDetailMapper().queryListBySchemeId(primaryId);
        encryptUtil.decryptList(insuranceSchemeDetailPOS, InsuranceSchemeDetailPO.class);
        return insuranceSchemeDetailPOS;
    }

    /**
     * 获取所有方案
     *
     * @return
     */
    @Override
    public List<InsuranceSchemePO> listAll(){

        List<InsuranceSchemePO> insuranceSchemePOList = getInsuranceSchemeMapper().listAll();
        return insuranceSchemePOList;
    }

    /*****以上代码为SISchemeBiz中方法逻辑迁移，旨在减少Biz类的使用*****/
}
